Héritage en Diamant

Le
Philippe MESMEUR
Bonjours à tous,

débutant en java je rencontre un problème (que j'imagine récurrent su=
r
ce forum), le problème de l'héritage en diamant.


Jusqu'à présent, quand j'ai un problème d'héritage multiple (une
classe A qui hérite de B et C), je cré une interface IB et IC, je fait
en sorte que B implémente IB, que C implémente IC puis je fais que A
implémente IB et IC et qu'il étende B. Enfin, j'ajoute un attribut c =
à
A, de type C et je redéfinie les méthodes de IC dans A de sorte
qu'elle appelle la méthode du même nom de l'attribut c. Un exemple
valant mieux qu'un long discours, voici ce que je fais:

class A extends B implement IB, IC
{
IC c = new C();

public uneMethodeDeIC()
{
c.uneMethodeDeIC();
}

}

Mais que ce passe-t-il si maintenant B et C héritent tous deux d'une
classe D ayant ses propres attributs (héritage en diamant)

Les méthodes de IB peuvent modifier les attribut de D; les méthodes de
IC également!

En appliquant cette problématique à mon exemple précédant, la class=
e A
possèderait les attribut de D via le "extends B" et l'attribut c
possèderait également les attribut de D. Mais du coup, il seraient
modifiés indépendamment ce qui peut poser de nombreux problème.

Y a-t-il une méthode "propre" pour gérer ce cas en java. J'imagine que
je ne suis pas le premier à avoir ce genre de problème; peut-être y a=
-
t-il des recommandations?

merci d'avance
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Christian Laborde
Le #22630081
IB et IC étant des interfaces, les méthodes ne sont pas
implémentées et ne peuvent rien faire.

Philippe MESMEUR a écrit :
Bonjours à tous,

débutant en java je rencontre un problème (que j'imagine récurrent sur
ce forum), le problème de l'héritage en diamant.


Jusqu'à présent, quand j'ai un problème d'héritage multiple (une
classe A qui hérite de B et C), je cré une interface IB et IC, je fait
en sorte que B implémente IB, que C implémente IC puis je fais que A
implémente IB et IC et qu'il étende B. Enfin, j'ajoute un attribut c à
A, de type C et je redéfinie les méthodes de IC dans A de sorte
qu'elle appelle la méthode du même nom de l'attribut c. Un exemple
valant mieux qu'un long discours, voici ce que je fais:

class A extends B implement IB, IC
{
IC c = new C();
...
public uneMethodeDeIC()
{
c.uneMethodeDeIC();
}
...
}

Mais que ce passe-t-il si maintenant B et C héritent tous deux d'une
classe D ayant ses propres attributs (héritage en diamant)...

Les méthodes de IB peuvent modifier les attribut de D; les méthodes de
IC également!

En appliquant cette problématique à mon exemple précédant, la classe A
possèderait les attribut de D via le "extends B" et l'attribut c
possèderait également les attribut de D. Mais du coup, il seraient
modifiés indépendamment ce qui peut poser de nombreux problème.

Y a-t-il une méthode "propre" pour gérer ce cas en java. J'imagine que
je ne suis pas le premier à avoir ce genre de problème; peut-être y a-
t-il des recommandations?

merci d'avance




--
Christian Laborde
La Révolution citoyenne, c'est sur : http://c.lab.over-blog.com/
Les citoyens qui voient Net : http://www.netoyens.info
True E-mail : remove -no-spam-
Sentier des Vinches
CH 1091 Grandvaux
Suisse
Philippe MESMEUR
Le #22630191
On 30 sep, 16:13, Christian Laborde
IB et IC étant des interfaces, les méthodes ne sont pas
implémentées et ne peuvent rien faire.




???

B implémente IB, et donc les méthodes de IB.
idem pour C et IC.

La classe A implémente les méthode de IB car elle étend B et elle
redéfinie toutes les méthode de IC en les redirigent vers l'attribut c
instancié par new B.

Philippe MESMEUR a écrit :



> Bonjours à tous,

> débutant en java je rencontre un problème (que j'imagine récurren t sur
> ce forum), le problème de l'héritage en diamant.

> Jusqu'à présent, quand j'ai un problème d'héritage multiple (un e
> classe A qui hérite de B et C), je cré une interface IB et IC, je f ait
> en sorte que B implémente IB, que C implémente IC puis je fais que A
> implémente IB et IC et qu'il étende B. Enfin, j'ajoute un attribut c à
> A, de type C et je redéfinie les méthodes de IC dans A de sorte
> qu'elle appelle la méthode du même nom de l'attribut c. Un exemple
> valant mieux qu'un long discours, voici ce que je fais:

>    class A extends B implement IB, IC
>    {
>      IC c = new C();
>    ...
>      public uneMethodeDeIC()
>      {
>        c.uneMethodeDeIC();
>      }
>    ...
>    }

> Mais que ce passe-t-il si maintenant B et C héritent tous deux d'une
> classe D ayant ses propres attributs (héritage en diamant)...

> Les méthodes de IB peuvent modifier les attribut de D; les méthodes de
> IC également!

> En appliquant cette problématique à mon exemple précédant, la c lasse A
> possèderait les attribut de D via le "extends B" et l'attribut c
> possèderait également les attribut de D. Mais du coup, il seraient
> modifiés indépendamment ce qui peut poser de nombreux problème.

> Y a-t-il une méthode "propre" pour gérer ce cas en java. J'imagine que
> je ne suis pas le premier à avoir ce genre de problème; peut-être y a-
> t-il des recommandations?

> merci d'avance

--
Christian Laborde
La Révolution citoyenne, c'est sur :http://c.lab.over-blog.com/
Les citoyens qui voient Net :http://www.netoyens.info
True E-mail : remove -no-spam-
Sentier des Vinches
CH 1091 Grandvaux
Suisse
Christian Laborde
Le #22630301
Une classe ne possède pas d'attribut sauf les attributs
static. Un attribut non static appartient à un objet.
Donc un objet de classe A peut avoir les mêmes attributs que
l'objet de la classe C, mais ce sont des variables
différentes en mémoire.

Philippe MESMEUR a écrit :
On 30 sep, 16:13, Christian Laborde
IB et IC étant des interfaces, les méthodes ne sont pas
implémentées et ne peuvent rien faire.




???

B implémente IB, et donc les méthodes de IB.
idem pour C et IC.

La classe A implémente les méthode de IB car elle étend B et elle
redéfinie toutes les méthode de IC en les redirigent vers l'attribut c
instancié par new B.

Philippe MESMEUR a écrit :



Bonjours à tous,
débutant en java je rencontre un problème (que j'imagine récurrent sur
ce forum), le problème de l'héritage en diamant.
Jusqu'à présent, quand j'ai un problème d'héritage multiple (une
classe A qui hérite de B et C), je cré une interface IB et IC, je fait
en sorte que B implémente IB, que C implémente IC puis je fais que A
implémente IB et IC et qu'il étende B. Enfin, j'ajoute un attribut c à
A, de type C et je redéfinie les méthodes de IC dans A de sorte
qu'elle appelle la méthode du même nom de l'attribut c. Un exemple
valant mieux qu'un long discours, voici ce que je fais:
class A extends B implement IB, IC
{
IC c = new C();
...
public uneMethodeDeIC()
{
c.uneMethodeDeIC();
}
...
}
Mais que ce passe-t-il si maintenant B et C héritent tous deux d'une
classe D ayant ses propres attributs (héritage en diamant)...
Les méthodes de IB peuvent modifier les attribut de D; les méthodes de
IC également!
En appliquant cette problématique à mon exemple précédant, la classe A
possèderait les attribut de D via le "extends B" et l'attribut c
possèderait également les attribut de D. Mais du coup, il seraient
modifiés indépendamment ce qui peut poser de nombreux problème.
Y a-t-il une méthode "propre" pour gérer ce cas en java. J'imagine que
je ne suis pas le premier à avoir ce genre de problème; peut-être y a-
t-il des recommandations?
merci d'avance


--
Christian Laborde
La Révolution citoyenne, c'est sur :http://c.lab.over-blog.com/
Les citoyens qui voient Net :http://www.netoyens.info
True E-mail : remove -no-spam-
Sentier des Vinches
CH 1091 Grandvaux
Suisse






--
Christian Laborde
La Révolution citoyenne, c'est sur : http://c.lab.over-blog.com/
Les citoyens qui voient Net : http://www.netoyens.info
True E-mail : remove -no-spam-
Sentier des Vinches
CH 1091 Grandvaux
Suisse
Yliur
Le #22630571
Le Thu, 30 Sep 2010 06:52:53 -0700 (PDT)
Philippe MESMEUR
Bonjours à tous,



Bonjour


débutant en java je rencontre un problème (que j'imagine récurrent sur
ce forum), le problème de l'héritage en diamant.



Java ne supporte pas l'héritage multiple, en partie parce que ça peut
amener des cas compliqués, mais aussi parce que les cas où c'est
nécessaire n'arrivent pas tellement souvent.



Jusqu'à présent, quand j'ai un problème d'héritage multiple (une
classe A qui hérite de B et C), je cré une interface IB et IC, je fait
en sorte que B implémente IB, que C implémente IC puis je fais que A
implémente IB et IC et qu'il étende B. Enfin, j'ajoute un attribut c à
A, de type C et je redéfinie les méthodes de IC dans A de sorte
qu'elle appelle la méthode du même nom de l'attribut c. Un exemple
valant mieux qu'un long discours, voici ce que je fais:

class A extends B implement IB, IC
{
IC c = new C();
...
public uneMethodeDeIC()
{
c.uneMethodeDeIC();
}
...
}



Il n'y a pas besoin d'écrire "implements IB" si B l'implémente déjà
(et si c'est bien déclaré dans B en écrivant "B implements IB").



Mais que ce passe-t-il si maintenant B et C héritent tous deux d'une
classe D ayant ses propres attributs (héritage en diamant)...

Les méthodes de IB peuvent modifier les attribut de D; les méthodes de
IC également!

En appliquant cette problématique à mon exemple précédant, la classe A
possèderait les attribut de D via le "extends B" et l'attribut c
possèderait également les attribut de D. Mais du coup, il seraient
modifiés indépendamment ce qui peut poser de nombreux problème.



Oui, c'est ennuyeux.


Y a-t-il une méthode "propre" pour gérer ce cas en java. J'imagine que
je ne suis pas le premier à avoir ce genre de problème; peut-être y a-
t-il des recommandations?



Ça ne concerne pas spécialement Java. De mémoire, en C++ les deux
attributs existent également et c'est au développeur de choisir s'il
veut accéder à l'attribut de D hérité à travers B ou à celui hérité à
travers C (en écrivant quelque chose du genre B::attributDeD ou
C::attributDeD). Donc si on utilise les méthodes de B ou de C on a le
même problème qu'en Java.


Il n'y a pas forcément de solution miracle, c'est au développeur de se
débrouiller selon les cas. Je n'ai pas trop d'idée générale qui
marcherait tout le temps.

Une remarque cependant : les cas où l'héritage multiple est nécessaire
(voire même simplement souhaitable) sont rares. La composition fait
souvent bien mieux l'affaire.

Peut-on avoir votre exemple concret ? Il est sans doute possible
d'organiser les classes autrement et de troquer l'héritage multiple
contre une solution plus souple et n'ayant pas ce problème.

Yliur
Testman
Le #22695601
On 30/09/2010 15:52, Philippe MESMEUR wrote:
Bonjours à tous,

débutant en java je rencontre un problème (que j'imagine récurrent sur
ce forum), le problème de l'héritage en diamant.


Jusqu'à présent, quand j'ai un problème d'héritage multiple (une
classe A qui hérite de B et C), je cré une interface IB et IC, je fait
en sorte que B implémente IB, que C implémente IC puis je fais que A
implémente IB et IC et qu'il étende B. Enfin, j'ajoute un attribut c à
A, de type C et je redéfinie les méthodes de IC dans A de sorte
qu'elle appelle la méthode du même nom de l'attribut c. Un exemple
valant mieux qu'un long discours, voici ce que je fais:

class A extends B implement IB, IC
{
IC c = new C();
...
public uneMethodeDeIC()
{
c.uneMethodeDeIC();
}
...
}




Bonjour Philippe,

Au passage, A implemente déjà IB via l'extension de B pas besoin de le
repréciser dans A ;-)

Mais que ce passe-t-il si maintenant B et C héritent tous deux d'une
classe D ayant ses propres attributs (héritage en diamant)...




Aucun problème, A hérite de B et D une seule fois. Mais la relation avec
C et D ne passe que par un membre de A. Il n'y a donc pas de problème,
car sont deux objects différents (this et this.c).

Les méthodes de IB peuvent modifier les attribut de D; les méthodes de
IC également!



C'est à ça que sert l'encaspulation. Si vos methodes sont des
accesseurs, à vous de voir si vous souhaitez propager la modification
d'attribut issues de IB sur la branche issue de C, sachant qu'en
l'instance vous avez donc bien deux contenant pour la partie aute du
diamant et non pas un seul comme dans le principe du diamant.


En appliquant cette problématique à mon exemple précédant, la classe A
possèderait les attribut de D via le "extends B" et l'attribut c
possèderait également les attribut de D. Mais du coup, il seraient
modifiés indépendamment ce qui peut poser de nombreux problème.




Non, car vous controlez le comportement. A vous de propager les
modiffications par setter des deux cotés ou pas.

Ceci ce fait généralement en fonction de la compatibilité des contrats
et de la sémantique entre IB et IC sur les propriétés communes.

Y a-t-il une méthode "propre" pour gérer ce cas en java. J'imagine que
je ne suis pas le premier à avoir ce genre de problème; peut-être y a-
t-il des recommandations?

merci d'avance




Le problème n'est pas rare, mais le fait que les contrat soit proche
permet que celà ne pose pas de problème.

Ainsi, on a des propriétés type id ou name ... en commun et celà ne pose
aucun problème en cas de simili-diamant.

Si par contre vous avez des interfaces qui ont des propriétés (par
exemple id) dans leur contrat mais n'ont pas la même sémantique. En
clair "que veut dire identifiant" ... alors là vous aurez un problème
avec une des branches.

Mais franchement, dans la vraie vie, je n'ai jamais croisé de problème
bloquant à ce niveau pour l'instant.

A+
TM
Publicité
Poster une réponse
Anonyme