java et pointeurs sur fonction - Java - Programmation
Marsh Posté le 08-04-2005 à 22:04:04
non, là le polymorphisme ne m'aide pas :
je veux pouvoir modifier le comportement de mon objet en modifiant ce qui est réalisé par une méthode "générique" que j'appellerai a partir d'un autre objet
p ex: un handler qui contiendrait un véhicule en appelant
handler.véhicule.avancer();
et véhicule.avancer() renverrait suivant le cas à
???.rouler(), ???.floter() ou ???.voler()
(??? paske je sais pas si ces fonctions doivent être dans véhicule ou ailleurs, peut etre une classe final avec un attribut static pour les méthodes ...)
bref, si vous savez comment faire ...
Marsh Posté le 08-04-2005 à 22:44:11
Il n'y a pas de concept de pointeur en Java, donc pas de pointeur sur fonctions ...
Cependant :
Citation : |
Marsh Posté le 08-04-2005 à 23:10:59
Ou bien: http://java.developpez.com/faq/jav [...] r_fonction
(mais pas testé)
Marsh Posté le 08-04-2005 à 23:20:54
oui effectivement ca a l'air pas mal, et donc il faut preparer plusieurs Class1.Callback et modifier first.callb quand on veut changer le comportement.
en fait ca doit même marcher avec des abstract. par contre pour utiliser la meme fonction générique dans plusieurs objets différents, et donc avec plusieurs comportements, ca fait ecrire pas mal de classe, limite une par comportement c moche
en tout cas, merci pour le conseil
edit: le second est sensiblement identique donc merci pour les conseils
Marsh Posté le 09-04-2005 à 01:10:08
TheRom_S a écrit : en fait ca doit même marcher avec des abstract. par contre pour utiliser la meme fonction générique dans plusieurs objets différents, et donc avec plusieurs comportements, ca fait ecrire pas mal de classe, limite une par comportement c moche |
en quoi c'est plus moche de devoir écire plusieurs classes plutot que de devoir écrire plusieurs méthodes ?
Marsh Posté le 09-04-2005 à 09:57:03
bref pour résumer, une solution efficace serait :
Code :
|
Code :
|
Code :
|
Code :
|
effectivement, ca fait une classe par fonction et c'est moche
sinon, il reste :
Code :
|
Code :
|
finalement, il faut voir que même si les pointeurs n'existent pas en java, c'est parceque chaque variable ou méthode peut être assimilée à un pointeur. Donc ret garde le lien vers la bonne fonction ... dont le résultat change de valeur lorsqu'on change les valeurs des opérandes !
bon il reste le problème du choix if(name=="func..." ) mais ça évite de le garder dans la définition de la fonctionet de le balancer à chaque appel. C'est donc peut-être plus joli que de faire une classe par fonction ...
Marsh Posté le 09-04-2005 à 10:03:46
TheRom_S a écrit : effectivement, ca fait une classe par fonction et c'est moche |
mais y a rien de moche à ça, au contraire !
(à part ta façon de définir une interface )
C'est très propre comme code. Bien plus qu'un pointeur de fonction à la con sur lequel tu risques de foirer ton passage d'argument parce qu'il n'y a aucun contrôle dessss.
C'est utilisé très très couramment en programmation objet ...
sinon, ta 2e solution, oublie, c'est n'importe quoi. Et fais attention : en java, la comparaisont de chaine se fait avec la méthode equals, pas avec l'opérateur '=='
Marsh Posté le 09-04-2005 à 10:35:06
effecitivement, je viens de tester la 2eme solution
ret n'est pas recalculé ! (uniquement lors de setFunc)
j'avais confondu avec un autre truc qui ressemble vaguement mais avec des fonctions et qu'on ne peut pas modifier :
classe 1 :
func() { ... class1.var ... }
classe 2 :
func() { return class1.func(); }
par contre, == fonctionne très bien
sinon, l'interface, c'est juste un copier/coller
donc je l'admet : j'ai écrit tout ca un peu vite et je suis grillé
Marsh Posté le 09-04-2005 à 10:55:19
ReplyMarsh Posté le 09-04-2005 à 13:38:32
et le paquetage java.lang.reflect ne peut pas aider ? (une simple piste de recherche... je n'en suis pas sur)
Marsh Posté le 09-04-2005 à 14:21:22
ça peut, mais dans ce cas là c'est pas la meilleure solution.
Marsh Posté le 09-04-2005 à 14:54:27
alors ca donnerait :
Code :
|
là on voit qu'il faut passer par des classes donc pas d'int et invoke renvoie un Object donc un Integer ici ... à ce moment là, il vaut mieux ne plus utiliser d'int mais direct des Integer sinon on risque de surcharger le code ...
vous pensez que ça fonctionne ?
edit : faut rajouter un classcast ds le return d'aileurs ...
Marsh Posté le 09-04-2005 à 14:57:44
R3g a écrit : ça peut, mais dans ce cas là c'est pas la meilleure solution. |
A la limite, je prefere quand meme pour pas faire une classe par fonction
par contre je me demande si des erreurs peuvent passer facilement la compilation. y'a de bons controles ?
Marsh Posté le 09-04-2005 à 18:12:05
TheRom_S a écrit : alors ca donnerait :
|
Ce code est horrible ! Utilise l'interface, c'est 100x plus object et fait pour traiter ce genre de problème. De +, flotter, rouler et voler ne correspondent pas de manière plus abstraite à bouger ?
Marsh Posté le 09-04-2005 à 18:21:24
ah c'est sur qu'avec les transfos int <-> Integer, c'est horrible
par contre bouger est peut-être trop abstrait, que penses-tu de "seDeplacer" ?
Marsh Posté le 09-04-2005 à 18:24:50
TheRom_S a écrit : A la limite, je prefere quand meme pour pas faire une classe par fonction |
A mon humble avis, tu as tort.
C'est courramment utilisé, même en C++, où on a pourtant les pointeurs sur fonction.
http://google.com/search?q=strategy+pattern
Marsh Posté le 09-04-2005 à 19:02:14
ben faut voir après à l'execution aussi.
c'est vrai que
- object.getClass().getDeclaredMethod(String,Class.forName(),Class.forName())
et
- method.invoke(Object,args ...)
c'est surement lourd en ressources par rapport à la méthode des fonctions-objets
en fait en regardant les sources, y'a deja tout un tas de vérifications avant d'appeler sun.reflect.invoke(obj,args) dont j'ai pas les sources ...
ok je me rends -> une classe par fonction snif
Marsh Posté le 09-04-2005 à 19:16:49
TheRom_S a écrit : ah c'est sur qu'avec les transfos int <-> Integer, c'est horrible |
C'est pas une question de conversion int / Integer en fait mais l'approche pas du tout orientée objet que tu prends et l'utilisation complètement exotique de la réflexion.
Je verrai bien un truc du genre:
Code :
|
Marsh Posté le 09-04-2005 à 19:34:52
je viens de découvrir java.lang.reflect donc ca peut etre exotique
d'ailleurs quelle est son utilisation principale ?
sinon, ton exemple est ok dans certains cas, mais pas pour une sorte de véhicule amphibie ...
en fait l'histoire est bien de pouvoir changer le comportement (ou sa stratégie j'ai l'impression qu'on dit) d'un objet "en live"
Marsh Posté le 09-04-2005 à 19:41:27
La réflexion permet d'interroger un objet pour qu'il te retourne dynamiquement sa description (entre autres), de créer des objets sans connaître leur type à l'avance...
En effet, pour une voiture amphibie, l'implémentation de bouger() doit être modifiée quand on passe de la terre à l'eau et vice versa. Mais ta voiture sachant qu'elle est amphibie devrait décider par elle-même de l'implémentation à utiliser. Comment ? Ton véhicule doit être "aware" du support sur lequel il repose. Ca pourrait être ton gestionnaire de véhicules qui les en informerait...
Ton véhicule amphibie est une sous-classe de voiture
Marsh Posté le 09-04-2005 à 19:59:27
ok je vois pour la réflexion
par contre, l'exemple de la voitre, bouger, etc ... est peut-etre mauvais. ce que je cherchais, c'etait de faire evoluer un objet un peu comme si on voulait lui faire changer de classe ou plutot de sous-classe. une voiture qu'on voudrait transformer en avion ou un decodeur de protocole qui changerait d'algo de décodage suivant le proto encapsulé. en fait ca permet de garder l'objet sans detruire/recreer a chaque changement, ce qui peut demander un gros effort de passage de contexte. bref, tu fais toujours la meme chose vu de loin, mais le detail change en fonction du contexte ou de l'etat. ca peut aussi permettre de reduire la taille de ton objet : au lieu de contenir un decodeur différent pour chaque protocole succeptible d'etre rencontré (ds cet exemple là) tu en as toujours un seul (donc une classe simple) qui peut faire différentes opérations.
Marsh Posté le 09-04-2005 à 20:01:07
TheRom_S a écrit : ok je vois pour la réflexion |
Tu as de la chance, le State Pattern s'implémente presque comme le Strategy Pattern.
Marsh Posté le 09-04-2005 à 20:47:15
héhé les patterns !
je viens de faire un tour sur un site qui parle de design pattern en général
http://exciton.cs.rice.edu/JavaRes [...] nPatterns/
le decorator pattern à l'air interressant aussi pour faire evoluer un objet dynamiquement
merci Lam's pour les patterns
Marsh Posté le 08-04-2005 à 20:51:18
Salut,
j'aimerai savoir si vous connaissez un moyen simple pour faire un equivalent de pointeur sur fonction en java
je rappelle le principe et mon but
en C, ca donnerait :
void fonc1() {}
void fonc2() {}
void fonc3() {}
void *myfonc
ensuite au choix
myfonc=&fonc1, myfonc=&fonc2 ou myfonc=&fonc3
sachant que les pointeurs en java ... et aussi, que je cherche pas de truc dans le genre
myfonc(String fonc) {
if (fonc=="fonc1" ) { ... }
if (fonc=="fonc2" ) { ... }
if (fonc=="fonc3" ) { ... }
}
bref, si vous avez des idées, je suis preneur
merci
---------------
The Rom's, à votre service