Fonctions static, surcharge et généric

neodelphi Messages postés 442 Date d'inscription jeudi 4 avril 2002 Statut Membre Dernière intervention 11 août 2008 - 7 août 2008 à 19:32
sheorogath Messages postés 2448 Date d'inscription samedi 21 février 2004 Statut Modérateur Dernière intervention 29 janvier 2010 - 11 août 2008 à 20:43
Bonjour, je suis en train de me plonger dans le Java afin de faire un site web à l'aide de servlets, mais je butte sur un problème en rapport avec le langage. Voici donc l'énoncé du problème (simplifié pour que ce soit plus clair) :

soit une classe Plante. Je souhaite dériver de cette classe des classes représentant des plantes et les décrivant. Par exemple une classe Rose et une classe Tuya.
Prenons ensuite une dernière classe Jardinier, donc le but est de mettre des plantes dans le jardin en fonction de leur couleur. Je souhaiterai faire appel au Jardinier de la façon suivante:



Jardinier.ajouterFleur(Rose.class);



ou bien



Jardinier.ajouterFleur(Tuya.class);



La classe Jardinier effectue des opérations dépendantes de la couleur des plantes, et doit donc faire appel à la méthode Rose.getColor ou Tuya.getColor. Je souhaite en fait que ces fonctions soient statiques, car elles renvoient une valeur qui n'est pas dépendante d'une instance mais uniquement spécifique à la classe. La déclaration de la fonction getColor doit donc pour moi se situer dans la classe Plante puis être surchargée par les classe héritant (équivalent à une fonction statique virtuelle en C++) mais le compilateur me gronde...

Dernière précision, la fonction ajouterFleur serait de la forme:

public void <F extends Plante> ajouterFleur(Class<F> classeFleur){
    ...
    ... F.getColor() ...
    ...
}

Hélas je ne trouve pas de solutions à ce problème pourtant simple, et je ne veut pas avoir à créer une instance pour appeler une fonction qui me renverra toujours la même valeur (ce que je peux en fait faire avec un singleton, mais bon...).

Tout conseil est bienvenu ! Merci pour votre aide !

neodelphi
A voir également:

15 réponses

Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 111
8 août 2008 à 09:17
Salut,

là comme ça je ne vois que le mécanisme de réflexion pour faire un invoque de ta méthode static...

------------------------------------
"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."

OoWORAoO
0
indiana_jules Messages postés 750 Date d'inscription mardi 9 mars 2004 Statut Membre Dernière intervention 23 décembre 2008 22
8 août 2008 à 13:14
Salut,

Une solution envisageable serait de créer une classe Abstraite du syle AbstractFleur qui contiendrait ta méthode statique, et pour chacune de tes classes héritant de celle-ci, tu surchargerais cette méthode là. Du coup, en paramétre de ta méthode "ajouterFleur", tu aurais Class<? extends AbstractFleur> ...

A tester (je ne peux pas garantir que cela va fonctionner, je n'ai pas d'envrionnement pour tester rapidement là où je suis à cette instant T :(       )

Voili voilà

le monde a des idées : la preuve, c'est qu'il y en a de mauvaises
ne comprends pas tout, mais je parle de tout : c'est ce qui compte
0
Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 111
8 août 2008 à 13:40
Salut,

la solution avec reflect soit en restant en accord avec l'origine de la question (perso je trouve la solution de [auteur/INDIANAJULES/242730.aspx indiana_jules] bien plus objet et beaucoup plus propre) :

import java.awt.Color;
import java.lang.reflect.Method;

public class ReflectStatic {
   
    public static void main(String[] args) {
        ReflectStatic rs = new ReflectStatic();
        try {
            rs.ajouterFleur(Rose.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public <F extends Plante> void ajouterFleur(Class<F> classeFleur) throws Exception {
        Method getColor = classeFleur.getMethod("getColor", new Class[] {});
        Color c = (Color)getColor.invoke(null, new Object[] {});
        System.out.println("getColor : " + c);
    }
   
    private static class Plante {
        // super caca puis la couleur vaut pour TOUTES les instances de TOUTES les plante....
        public static Color getColor() {
            return Color.RED;
        }
    }
   
    private static class Rose extends Plante {
       
    }
}

------------------------------------
"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."

OoWORAoO
0
neodelphi Messages postés 442 Date d'inscription jeudi 4 avril 2002 Statut Membre Dernière intervention 11 août 2008
9 août 2008 à 12:58
Rebonjour !

Merci pour vos réponse, c'est sympa de pouvoir discuter de ce problème. Twinuts, j'avait un peu réfléchi à cette solution qui fonctionnerait sans doute, mais je n'aime pas du tout cette philosophie et je considère ça comme du hack ou de la bidouille, il n'y pas vraiment de vérifications faites par le compilo sur le code du programmeur... de plus l'appel de la fonction est assez lourd en terme de performances.

Indiana_jules, la surcharge de fonctions statique fonctionne sur des instances, mais à moitié sur des statics. Je m'explique:

class A {
    static void test(){ écrire 'A' }
}

class B extends A {
    static void test(){ écrire 'B' }
}

Si on fait B.test() on obtiend 'B' comme attendu. Si on passe la classe au travers des génériques, de cette façon:

public static <E extends A> String test(Class<E> c){
    return E.test();
}

en fesant test(B.class) on obtien 'A' et non 'B', comme si la surcharge est ignorée. Je trouve que ça fait un peu "bug" comme résultat mais bon, certains disent que c'est la surchage des static qui ne devrait pas marcher si c'était bien foutu.....

J'ai vu des programmeurs recommandant d'utiliser les singletons pour avoir le comportement normal des surcharges, mais je trouve dommage de ne pas utiliser les statics lorsque cela semble logique étant donné que les instances n'apportent rien.

neodelphi
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
indiana_jules Messages postés 750 Date d'inscription mardi 9 mars 2004 Statut Membre Dernière intervention 23 décembre 2008 22
9 août 2008 à 13:55
Salut
si tu utilises une version 1.5 ou plus récente, tu peux peut-être mettre une annotation "override" pour bien préciser à la JVM qu'il s'agt d'une surcharge. Peut-êre que cela marchera mieux.

A++

le monde a des idées : la preuve, c'est qu'il y en a de mauvaises
ne comprends pas tout, mais je parle de tout : c'est ce qui compte
0
Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 111
9 août 2008 à 13:57
Salut,

"de plus l'appel de la fonction est assez lourd en terme de performances."
>> détrompe toi

Pour le reste la surcharge avec du static ne sert absolument à rien.... car elle impact absolument tous les objets (même dérivés).... en bref ce que Indiana_jules (corrige moi si je me trompe indi) veux te faire comprendre c'est qu'ici il ne faudrait pas utiliser le static (en plus non justifié)

"mais je trouve dommage de ne pas utiliser les statics lorsque cela semble logique étant donné que les instances n'apportent rien"
>> Tu ne dois pas avoir saisi la portée de static pour dire ça... en gros ce que tu veux faire (enfin le code que tu présentes depuis le début) reviendrait à avoir une seule et unique couleur pour TOUTES les plantes...

------------------------------------
"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."

OoWORAoO
0
neodelphi Messages postés 442 Date d'inscription jeudi 4 avril 2002 Statut Membre Dernière intervention 11 août 2008
9 août 2008 à 14:18
En fait je souhaitai le static chez les classes héritant, et je pensais l'imposer en proposant la méthode en abstrait. Ainsi en donnant un objet Plante le compilateur saurait que quelque soit la classé héritant, il existe la fonction getColor qui peut être appelée sans créer d'instances.

Je justifie l'utilisation du static en expliquant que quelque soit l'instance de Rose, la fonction getColor renvoie toujours la meme valeur. De même pour Tuya, la fonction renvoie toujours la même valeur. C'est du static appliqué à la classe et non à l'ensemble des classes héritant de Plante.

Pour moi une fonction ne doit pas être statique dès que son résultat dépend de l'instance sur laquelle la fonction est appelée.

"de plus l'appel de la fonction est assez lourd en terme de performances."
">> détrompe toi"

Pourtant il ne s'agit plus d'un simple saut, par exemple une instance de Method est crée et des appels d'autres fonctions sont exécutées. L'appel est donc au moins 3 fois plus lourd je pense.

neodelphi
0
sheorogath Messages postés 2448 Date d'inscription samedi 21 février 2004 Statut Modérateur Dernière intervention 29 janvier 2010 17
9 août 2008 à 15:56
"Je justifie l'utilisation du static en expliquant que quelque soit
l'instance de Rose, la fonction getColor renvoie toujours la meme
valeur. De même pour Tuya, la fonction renvoie toujours la même valeur.
C'est du static appliqué à la classe et non à l'ensemble des classes
héritant de Plante."

une rose peut etre rouge, blanche, jaune ....

pourquoi pas une interface ?
0
indiana_jules Messages postés 750 Date d'inscription mardi 9 mars 2004 Statut Membre Dernière intervention 23 décembre 2008 22
9 août 2008 à 16:34
Salut,

Effectivement Twinuts, je trouve que l'utilisation d'un static dans ce cadre là est superflu, d'autant plus sheoragatha raison, une rose peut avoir plusieurs couleurs. Du coup, l'utilisation d'une classe abstraite, d'une interface, ou des deux est fortement conseillé. Après, je me posais la question de savoir si on pouvait faire la même chose sur une méthode statique

Je sais que j'ai vu des API (exemple JXTA) qui te "forçait" à déclarer une méthode statique à la classe, en te levant une exception lors de l'insertion / utilisation (il devait faire de l'introspection sans doute pour la détecter).

Néanmoins, le static, il ne faut l'utiliser, soit pour des constantes, soit pour des méthodes "utilitaires", soit pour le singleton. Pour tout le reste, je trouve que ca ne peut apporter que du code spaghetti et assez hideux. Du coup, une bonne approche Objet est conseillé.

Voili voilà

le monde a des idées : la preuve, c'est qu'il y en a de mauvaises
ne comprends pas tout, mais je parle de tout : c'est ce qui compte
0
Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 111
9 août 2008 à 19:10
Salut,

pour le static abstrait il me semble avoir lu sur le site de sun qu'ils comptent le mettre en place pour le jdk 1.7... bien que perso je m'en cogne j'aime pas spécialement le static dans mes objets (trop crade)....

mais je suis à 200% avec vous les mecs (^^), l'utilisation des interfaces et des classes abstraites répondent à tous les maux du monde :) et permettent d'avoir une parfaite (et belle) structure OO qui je maintient ici est plus que necessaire (surtout pour la couleur)

------------------------------------
"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."

OoWORAoO
0
neodelphi Messages postés 442 Date d'inscription jeudi 4 avril 2002 Statut Membre Dernière intervention 11 août 2008
9 août 2008 à 19:28
Humm en fait je vais devoir utiliser les singletons car visiblement il n'est pas possible de faire du static abstrait. Selon moi le static ne s'oppose pas à la POO, bien au contraire. Disons que le point de vue java est différent du point de vue C++ où ce genre de méthodes est très utilisée car il y a derrière des considérations importantes au niveau performances. Le static ce n'est pas le mal !

Faut-il créer une instance pour appeler une fonction qui renvoie la liste des atomes dans la molécule d'eau ? Pour moi l'instanciation n'est pas utile dans cet exemple... Tant mieux si ils ajoutent la fonctionnalité dans le prochain jdk, c'est que je ne doit pas être le seul à rencontrer le problème !

neodelphi
0
Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 111
9 août 2008 à 19:50
" Disons que le point de vue java est différent du point de vue C++"
>> le static en java n'a quasiment rien du static C++, j'ai l'impression que c'est pour cela que tu penses que son utilisation (java) est justifiée...

"Le static ce n'est pas le mal"
>> en java c'est proche du diable incarné, car le static java reste et restera (pour le moment, qui sait pour le future) la meilleure méthode anti objet...

"c'est que je ne doit pas être le seul à rencontrer le problème"
>> Il y a des cas ou c'est apprécié, mais faut-il avant tout bien maitriser sa portée en java

------------------------------------
"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."

OoWORAoO
0
sheorogath Messages postés 2448 Date d'inscription samedi 21 février 2004 Statut Modérateur Dernière intervention 29 janvier 2010 17
9 août 2008 à 22:28
on pourrait tres bien dev sans static en java ...
apres je suis d'accord les methodes static sont purement anti OO
si ce n'est pour une legere optimisation les methodes static ne devrais pas etre possible

"n'est pas mort ce qui semble a jamais dormir et en d'etrange temps meme la mort peut mourrir"
0
neodelphi Messages postés 442 Date d'inscription jeudi 4 avril 2002 Statut Membre Dernière intervention 11 août 2008
11 août 2008 à 10:04
Effectivement le static en java, ça pu... Mais je voit pas comment faire pour partager une variable entre différentes instances d'une même classe. Mon expérience en C++ me perturbe énormément pour développer en Java !

neodelphi
0
sheorogath Messages postés 2448 Date d'inscription samedi 21 février 2004 Statut Modérateur Dernière intervention 29 janvier 2010 17
11 août 2008 à 20:43
la le static est justifie
sois tu explique mal sois on est 2 a etre un peu paumme

"n'est pas mort ce qui semble a jamais dormir et en d'etrange temps meme la mort peut mourrir"
0
Rejoignez-nous