IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Java Discussion :

[Heritage] redéclaration d'attributs


Sujet :

Langage Java

  1. #1
    Membre averti
    Inscrit en
    Avril 2002
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Avril 2002
    Messages : 36
    Par défaut [Heritage] redéclaration d'attributs
    Bonjour à tous, voilà quelques temps que je n'atais pas passé mais je me suis dit que ce petit problème pouvait être intéressant : dans le cadre d'un projet assez dense et assez peu documenté je viens de tomber dans un cas d'héritage que je ne pensais pas possible.

    De manière simplifiée ca se résume au cas de test suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
     
    public class TestHeritage {
     
    	public static void main(String[] args) {
    		Test2 test = new Test2();
    		System.out.println(test.getTest());
    		System.out.println(((Test1)test).getTest());
     
    		test.setTest(-1);
    		System.out.println(((Test1)test).getTest());
    		((Test1)test).setTest(-1);
    		System.out.println(((Test1)test).getTest());
     
    		System.out.println(test.superGetTest());
    		System.out.println(test.superAccesDirect());
    	}
    }
     
    class Test1 {
    	int test = 0;
     
    	public int getTest(){
    		return test;
    	}
     
    	public void setTest(int tt){
    		test = tt;
    	}
    }
     
    class Test2 extends Test1 {
    	int test = 10;
     
    	public int getTest(){
    		return 55;
    	}
     
    	public void setTest(int tt){
    		test = tt+100;
    	}
     
    	public int superGetTest(){
    		return super.getTest();
    	}
     
    	public int superAccesDirect(){
    		return super.test;
    	}
    }
    Dans le projet je suis certain que l'apparition de cette surcharge d'attribut n'est pas volontaire est j'aimerais comprendre les conséquences que cela peut avoir, car les quelques tests que j'ai pu réaliser me montrent certains fonctionnements mais sûrement pas l'exhaustivité des cas.

    De plus je serais intéressé par savoir quelles sont les utilisations possibles (quand c'est maitrisé) de ce genre de surcharge, car pour moi ca ne devrait pas compiler car ca génère sur mon instance 2 attributs ayant le même nom et des valorisations différentes.

    Merci d'avance,

    A titre indicatif, ca a été réalisé sous java 1.3 et je n'ai pas testé sous d'autres versions.

  2. #2
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,


    En réalité il n'y a pas de redéfinition ni d'héritage mais juste un conflit de nom. Les attributs sont référencé par leurs noms complets (package + nom de la classe + nom de l'attribut).

    Ainsi ici tu as deux champs distincts Test1.test et Test2.test...


    a++

  3. #3
    Membre averti
    Inscrit en
    Avril 2002
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Avril 2002
    Messages : 36
    Par défaut
    Merci pour la réponse ^^

    Par contre, ce que je ne comprends pas et que je trouve assez troublant c'est que ce conflit de nom ne soit pas levée (au moins en warning) à la compilation, mais j'ai peut-être mal configuré mes options de compilation.

    Ce qui est aussi assez dérangeant c'est pour la déclaration des accesseurs qui devient très ambigüe :

    Si un accesseur est surchargé dans la classe Test2, c'est l'attribut Test2.test qui est touché, si il n'y a pas de surcharge c'est l'attribut Test1.test.

    Donc surcharger un setter mais pas un getter dans la classe génère des comportements explicables mais pas forcément intuitifs.

    Donc pour poursuivre la question est-ce que ce conflit de nom correspond à une mauvaise pratique à éviter ou est-il possible de l'utiliser dans certains pattern ou fonctionnalités cibles ?

    La on s'éloigne de mon problème pratique puisque j'ai "résolu" mon problème en différenciant explicitement les deux attributs en leur fournissant des nom différents, mais les comportements potentiels (et encore je n'ai pas joué avec les niveau de visibilité des attributs) me troublent un peu.

  4. #4
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par lando
    Donc pour poursuivre la question est-ce que ce conflit de nom correspond à une mauvaise pratique à éviter ou est-il possible de l'utiliser dans certains pattern ou fonctionnalités cibles ?
    Perso je te conseille fortement de les éviter ! Surtout que cela n'apporte rien de plus que d'utiliser un attribut avec un nom différent...



    Quand au compilateur javac, il ne signale pas ce type "d'erreur", mais certain EDI comme eclipse ou NetBeans peuvent le faire (mais ce n'est pas le cas par défaut il me semble).


    a++

  5. #5
    Membre chevronné
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    365
    Détails du profil
    Informations personnelles :
    Localisation : Maroc

    Informations forums :
    Inscription : Janvier 2006
    Messages : 365
    Par défaut
    On pourrait très bien l'appeler "redéfinition", puisqu'il s'agit tout de même de masquer l'attribut défini dans la classe de base. Ceci est bien évidemment permis par le compilateur, d'ailleurs l'interdire aurait compliquer encore plus les choses pour le langage Java. Imagine toutes ces classes de différentes librairies que l'on hérite dans nos programmes, on ne cherche pas à savoir le détail de leur implémentation, ce qui fait qu'on pourrait très bien sans le savoir déclarer un attribut ayant le même nom qu'un attribut de la classe de base.
    Mais comme le dit adiGuba, on a effectivement deux champs distincts, Test1.test et Test2.test. La différence se situe au niveau du polymorphisme, c'est-à-dire que l'appel de la méthode getTest() par exemple te retournera l'attribut du type effectif de la variable, alors que l'instruction "var.test;" te donnera soit Test1.test, soit Test2.test, selon que var est de type Test1 ou Test2 car la liaison est statique (forcée à la compilation), contrairement à la liaison dynamique dans le cas d'une méthode polymorphe.
    Bien entendu, une visibilité "private" dans la classe de base rend l'attribut invisible dans les classes dérivées.
    Voilà, j'espère n'avoir pas trop compliqué les choses avec mes explications un peu laborieuses, je le reconnais

  6. #6
    Membre averti
    Inscrit en
    Avril 2002
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Avril 2002
    Messages : 36
    Par défaut
    Merci encore pour vos réponses.

    Citation Envoyé par manblaizo
    On pourrait très bien l'appeler "redéfinition", puisqu'il s'agit tout de même de masquer l'attribut défini dans la classe de base. Ceci est bien évidemment permis par le compilateur, d'ailleurs l'interdire aurait compliquer encore plus les choses pour le langage Java. Imagine toutes ces classes de différentes librairies que l'on hérite dans nos programmes, on ne cherche pas à savoir le détail de leur implémentation, ce qui fait qu'on pourrait très bien sans le savoir déclarer un attribut ayant le même nom qu'un attribut de la classe de base.
    Effectivement je réfléchissais au niveau de mes packages, mais je comprends mieux pourquoi ce n'est pas bloquant pour le compilateur.

    Citation Envoyé par manblaizo
    Mais comme le dit adiGuba, on a effectivement deux champs distincts, Test1.test et Test2.test. La différence se situe au niveau du polymorphisme, c'est-à-dire que l'appel de la méthode getTest() par exemple te retournera l'attribut du type effectif de la variable, alors que l'instruction "var.test;" te donnera soit Test1.test, soit Test2.test, selon que var est de type Test1 ou Test2 car la liaison est statique (forcée à la compilation), contrairement à la liaison dynamique dans le cas d'une méthode polymorphe.
    Bien entendu, une visibilité "private" dans la classe de base rend l'attribut invisible dans les classes dérivées.
    Voilà, j'espère n'avoir pas trop compliqué les choses avec mes explications un peu laborieuses, je le reconnais
    Non, c'était un peu le but de la poursuite de la discussion. Il faudra bien entendu que je joue un peu plus avec le polymormiphisme, mais a priori ce type de code peut arriver mais n'a pas d'apport. C'est plus de l'ordre de l'accidentel et à éviter quand on a la visibilité suffisante.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. heritage et attributs
    Par piotrr dans le forum VB 6 et antérieur
    Réponses: 1
    Dernier message: 03/08/2007, 10h08
  2. feinter l'attribut private lors de l'heritage
    Par LittleBean dans le forum Langage
    Réponses: 11
    Dernier message: 24/04/2007, 18h04
  3. [Access] select heritage selon attribut
    Par Bapt.ice dans le forum Langage SQL
    Réponses: 8
    Dernier message: 25/04/2006, 16h25
  4. Réponses: 7
    Dernier message: 18/10/2005, 12h50
  5. [POO] Heritage d'attribut statique surchargé !
    Par Jaxofun dans le forum Langage
    Réponses: 25
    Dernier message: 16/08/2005, 09h01

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo