Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Héritage multiple en Java

5 réponses
Avatar
Vincent Belaïche
Bonjour,

Je débute en Java, et par rapport au C++ je trouve bien dommage que l'héritage
multiple ne soit pas supporté.

Bien sûr il y a les inteface, mais est-il possible de rediriger l'inteface
d'une classe vers la même interface de l'un de ses attribut. C'est à dire,
est-ce que ce n'est pas possible d'avoir un truc du genre:

--8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<---
public interface TutuInterface
{
void duTutu();
void encoreDuTutu();
void etEncoreDuTutu();
}

class Tutu implements TutuInterface
{

Tutu(TutuContext){ ... }

void duTutu(){ ...}
void encoreDuTutu(){ ...}
void etEncoreDuTutu(){ ...}

};




class Toto extends TotoBase implements TutuInterface
{
TutuContext context = new TutuContext();

private monTutu = new Tutu(context);

***redirige le TutuInteferace de this sur le TutuInteferace de monTutu***
}
--8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<---

Par

***redirige le TutuInteferace de this sur le TutuInteferace de monTutu***

je veux dire que les méthodes duTutu, encoreDuTutu, et etEncoreDuTutu de
l'inteface TutuInterface sont implantée par l'attribut monTutu.

C'est à dire que si j'ai

Toto toto = new Toto();

et que je fais toto.duTutu(), ça fait pareil que toto.monTutu.duTutu().

Merci d'avance,
Vincent.

5 réponses

Avatar
Sylvain SF
Vincent Belaïche a écrit :

Je débute en Java, et par rapport au C++ je trouve bien dommage que
l'héritage multiple ne soit pas supporté.



une classe peut implémenter plusieurs interfaces et donc simuler
(faire mieux que) un héritage multiple.

Bien sûr il y a les interface, mais est-il possible de rediriger
l'interface d'une classe vers la même interface de l'un de ses attribut.



pas "automatiquement".

public interface TutuInterface {


abstract public void duTutu();
}

class Tutu implements TutuInterface {
void duTutu(){ ...}
};

class Toto extends TotoBase implements TutuInterface
{
private monTutu = new Tutu(...);


public void duTutu(){
monTutu.duTutu();
}
}



Sylvain.
Avatar
Samuel Devulder
Vincent Belaïche a écrit :
Bonjour,

Je débute en Java, et par rapport au C++ je trouve bien dommage que
l'héritage multiple ne soit pas supporté.

Bien sûr il y a les inteface, mais est-il possible de rediriger
l'inteface d'une classe vers la même interface de l'un de ses attribut.
C'est à dire, est-ce que ce n'est pas possible d'avoir un truc du genre:

--8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<---
public interface TutuInterface
{
void duTutu();
void encoreDuTutu();
void etEncoreDuTutu();
}

class Tutu implements TutuInterface
{

Tutu(TutuContext){ ... }

void duTutu(){ ...}
void encoreDuTutu(){ ...}
void etEncoreDuTutu(){ ...}

};




class Toto extends TotoBase implements TutuInterface
{
TutuContext context = new TutuContext();

private monTutu = new Tutu(context);

***redirige le TutuInteferace de this sur le TutuInteferace de monTutu***
}
--8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<---

Par

***redirige le TutuInteferace de this sur le TutuInteferace de monTutu***




Pour faire cela il te faut utiliser le mécanisme de délégation: tu
délègue l'interface tutuInterface à l'object monTutu. A la main c'est
pas compliqué:
void duTutu() {
monTutu.duTutu();
}
void encoreDuTutu() {
monTutu.encoreDuTutu();
}
...
Bon c'est chiant.. et pas d'un grand intérêt à lire.


Mais avec un bon IDE (eclipse par exemple) il te génére automatiquement
ces méthodes délégées.

Cela dit, le remplacement n'est pas automatique. Si tu changes la
définition de tutuInterface() en ajoutant ou supprimant une méthode, il
faudra que tu ajoutes ou retires manuellement (ou via quickfix sous
eclipse peut-etre) les fonctions manquantes dans Toto.

J'imagine qu'il doit être possible de faire un plugin pour eclipse pour
qu'il supporte une annotation à lui style @delegate, pour qu'il ajoute
et maintiennent les méthodes issues de la délégation.. mieux, il
pourrait automatiquement replier ou masquer ces méthodes qui occupent de
la place pour pas grand chose.

sam.
Avatar
Vincent Belaïche
OK,

Je pensais que Java permettait de faire ça en une seule ligne, un peu comme en
C++ si tu fais explicitement un opérateur de cast du genre:


class Toto : TutuInterface
{
private:
Tutu monTutu;
public:
(operator TutuInterface&)(){ return monTutu; }
};


M'enfin bon... Merci quand même pour vos réponses !

Vincent.

Samuel Devulder a écrit :
Vincent Belaïche a écrit :
Bonjour,

Je débute en Java, et par rapport au C++ je trouve bien dommage que
l'héritage multiple ne soit pas supporté.

Bien sûr il y a les inteface, mais est-il possible de rediriger
l'inteface d'une classe vers la même interface de l'un de ses
attribut. C'est à dire, est-ce que ce n'est pas possible d'avoir un
truc du genre:

--8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<---
public interface TutuInterface
{
void duTutu();
void encoreDuTutu();
void etEncoreDuTutu();
}

class Tutu implements TutuInterface
{

Tutu(TutuContext){ ... }

void duTutu(){ ...}
void encoreDuTutu(){ ...}
void etEncoreDuTutu(){ ...}

};




class Toto extends TotoBase implements TutuInterface
{
TutuContext context = new TutuContext();

private monTutu = new Tutu(context);

***redirige le TutuInteferace de this sur le TutuInteferace de monTutu***
}
--8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<---

Par

***redirige le TutuInteferace de this sur le TutuInteferace de monTutu***




Pour faire cela il te faut utiliser le mécanisme de délégation: tu
délègue l'interface tutuInterface à l'object monTutu. A la main c'est
pas compliqué:
void duTutu() {
monTutu.duTutu();
}
void encoreDuTutu() {
monTutu.encoreDuTutu();
}
...
Bon c'est chiant.. et pas d'un grand intérêt à lire.


Mais avec un bon IDE (eclipse par exemple) il te génére automatiquement
ces méthodes délégées.

Cela dit, le remplacement n'est pas automatique. Si tu changes la
définition de tutuInterface() en ajoutant ou supprimant une méthode, il
faudra que tu ajoutes ou retires manuellement (ou via quickfix sous
eclipse peut-etre) les fonctions manquantes dans Toto.

J'imagine qu'il doit être possible de faire un plugin pour eclipse pour
qu'il supporte une annotation à lui style @delegate, pour qu'il ajoute
et maintiennent les méthodes issues de la délégation.. mieux, il
pourrait automatiquement replier ou masquer ces méthodes qui occupent de
la place pour pas grand chose.

sam.


Avatar
Samuel Devulder
Vincent Belaïche a écrit :
OK,

Je pensais que Java permettait de faire ça en une seule ligne, un peu
comme en C++ si tu fais explicitement un opérateur de cast du genre:


class Toto : TutuInterface
{
private:
Tutu monTutu;
public:
(operator TutuInterface&)(){ return monTutu; }
};


M'enfin bon... Merci quand même pour vos réponses !



Hélas non.. Du reste les opérateurs ne sont pas surchargeables en java.

Cependant tu peux faire l'equivalent en disant que ca n'est pas toto qui
implemente l'interface, mais il lui fourni un accès.

class Toto {
private Tutu monTutu;
public Tutu asTutu() {
return monTutu;
}
}

Donc en C++ là où tu aurais fait:
Toto toto = ...

((Tutu)toto).duTutu();

Tu fera en java:
Toto toto = ...

toto.asTutu().duTutu();

C'est kifkif car finalement ton operateur de cast te fait exactement la
même chose que la fonction asTutu() qui permet de voir l'objet toto
comme un Tutu(). Je trouve même cela perso plus clair et moins chiant
avec une fonction plutôt qu'avec le cast est ses trop nombreuses
parenthèses.

A noter que si toto implemente déjà lui même l'interface tutu, il suffit
alors d'ecrire:
public Tutu asTutu() {return this;}
Et du coup l'ecriture via asTutu() marche dans tous les cas, que l'objet
soit un tutu ou pas.

En fait, je me rend compte que ta problématique initiale d'utiliser
l'héritage multiple n'est pas vraiment le soucis. Ce que tu veux n'est
pas qu'un objet Toto soit aussi un objet Tutu en réalité, mais tu
voulais juste utiliser l'héritage multiple pour "hériter du code", ce
qui n'est pas souhaitable du tout en java. En fait, plutôt que d'hériter
du code, ce que tu voulais, c'est avoir une vue de toto en tant que
Tutu. C'est précisément ce que fourni la fonction asTutu(): elle te
donne accès à la facette tutu de toto, sans pour autant assumer que Toto
et Tutu sont un seul et même objet. Cela evite en outre la mauvaise
pratique qui consisterait à avoir dans le code des abominations comme:
Tutu tutu = ....;
((Toto)tutu).duToto();
C'est à dire à considérer que tout tutu est en fait du Toto aussi.
Avatar
TestMan
On 12/06/2009 06:50, Vincent Belaïche wrote:
Bonjour,

Je débute en Java, et par rapport au C++ je trouve bien dommage que
l'héritage multiple ne soit pas supporté.

Bien sûr il y a les inteface, mais est-il possible de rediriger
l'inteface d'une classe vers la même interface de l'un de ses attribut.
C'est à dire, est-ce que ce n'est pas possible d'avoir un truc du genre:

--8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<---
public interface TutuInterface
{
void duTutu();
void encoreDuTutu();
void etEncoreDuTutu();
}

class Tutu implements TutuInterface
{

Tutu(TutuContext){ ... }

void duTutu(){ ...}
void encoreDuTutu(){ ...}
void etEncoreDuTutu(){ ...}

};




class Toto extends TotoBase implements TutuInterface
{
TutuContext context = new TutuContext();

private monTutu = new Tutu(context);

***redirige le TutuInteferace de this sur le TutuInteferace de monTutu***
}
--8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<---

Par

***redirige le TutuInteferace de this sur le TutuInteferace de monTutu***

je veux dire que les méthodes duTutu, encoreDuTutu, et etEncoreDuTutu de
l'inteface TutuInterface sont implantée par l'attribut monTutu.

C'est à dire que si j'ai

Toto toto = new Toto();

et que je fais toto.duTutu(), ça fait pareil que toto.monTutu.duTutu().

Merci d'avance,
Vincent.




Bonjour Vincent,

Réponse tardive ... mais réponse :P

Oui, c'est possible par un proxy de façade :
http://java.sun.com/javase/6/docs/api/java/lang/reflect/Proxy.html

En gros tu vas implémenter un InvocationHandler qui prend ton instance
TotoBase en paramétre du constructeur de l'implémentation et sur appel
d'une méthode X (callback sur invoke) appelle le même nom de méthode et
signature sur l'objet du champ monTutu :)

Tu peux au besoin faire une adaptation de nom, de signature, .... ou de
tout :)

Un exemple:
http://www.javaworld.com/javaworld/jw-11-2000/jw-1110-proxy.html

Te reste simplement à créer à la demande ton instance de proxy avec son
handler (en ciblant l'objet souhaité) pour obtenir un objet qui
ressemble à TutuInterface :D

A+
TM