Je sais qu'une classe peut implémenter plusieurs interfaces, mais est-il possible d'étendre plusieurs classes? Par exemple, je souhaite que ma classe étende à la fois TransformGroup
et une classe que j'ai créée. Est-ce possible en Java? Les deux instructions class X extends TransformGroup extends Y
et class X extends TransformGroup, Y
reçoivent une erreur. Et si ce n'est pas possible, pourquoi? TransformGroup
étend Group
mais j'imagine qu'il étend également Node
puisqu'il hérite des champs de Node
et qu'il peut être transmis lorsqu'un objet Node
est requis. En outre, comme toutes les classes en Java, elles étendent la classe Object
. Alors, pourquoi ne serait-il pas possible d'étendre avec plus d'une classe?
Donc, si cela est possible, quelle est la bonne façon de le faire? Et si non, pourquoi et comment devrais-je résoudre le problème?
En Java, l'héritage multiple n'est pas autorisé. Il a été exclu du langage en tant que décision de conception, principalement pour éviter les dépendances circulaires.
Scénario 1: Comme vous avez appris ce qui suit n’est pas possible en Java:
public class Dog extends Animal, Canine{
}
Scénario 2: Toutefois, les possibilités suivantes sont possibles:
public class Canine extends Animal{
}
public class Dog extends Canine{
}
La différence entre ces deux approches réside dans le fait que dans la seconde approche, il existe une classe parent ou super
clairement définie, tandis que dans la première, la classe super
est ambiguë.
Déterminez si Animal
et Canine
avaient tous deux une méthode drink()
. Dans le premier scénario, quelle méthode parente serait appelée si nous appelions Dog.drink()
? Dans le deuxième scénario, nous savons que l'appel de Dog.drink()
appellera la méthode Canine
classes drink
tant que Dog
ne l'a pas remplacée.
En Java, l'héritage multiple n'est pas autorisé pour les implémentations (classes) uniquement pour les interfaces:
interface A extends B, C
Par exemple. MouseInputListener extend MouseListener et MouseMotionListener
Et, bien sûr, une classe peut implémenter plusieurs interfaces:
class X implements A, F
Non, ce n'est pas possible en Java (Peut-être qu'en Java 8, ce sera disponible). Acceptez le cas lorsque vous prolongez dans un arbre. Par exemple:
class A
class B extends A
class C extends B
Il n'y a pas de concept d'héritage multiple en Java. Seules plusieurs interfaces peuvent être implémentées.
Héritage multiple http://bit.ly/1Z62XjI
Supposons que B et C redéfinissent la méthode héritée et leur propre implémentation. Maintenant, D hérite des deux B & C en utilisant l'héritage multiple. D devrait hériter de la méthode surchargée. La question est de savoir quelle méthode surchargée sera utilisée? Sera-ce de B ou C? Ici nous avons une ambiguïté. Pour exclure une telle situation, l'héritage multiple n'a pas été utilisé en Java.
L'héritage multiple n'est pas possible avec class, vous pouvez le réaliser à l'aide d'une interface mais pas avec class. C'est par la conception du langage Java. Regardez un commentaire de James Gosling.
par James Gosling en février 1995 donne une idée sur pourquoi multiple l'héritage n'est pas pris en charge en Java.
Java en omet beaucoup, rarement utilisé, mal compris, déroutant caractéristiques de C++ qui, dans notre expérience, apporte plus de chagrin que d'avantage. Ce consiste principalement en une surcharge de l'opérateur (bien qu'il y ait une surcharge de la méthode ), un héritage multiple et une extension automatique étendue coercitions.
Java n'a pas fourni l'héritage multiple.
Lorsque vous dites A étend B, cela signifie que A étend B et B étend Object.
Cela ne signifie pas que A étend B, Object.
class A extends Object
class B extends A
Java ne peut pas supporter plusieurs héritages. Mais vous pouvez le faire de cette façon
class X
{
}
class Y extends X
{
}
class Z extends Y{
}
La plupart des réponses fournies semblent supposer que toutes les classes dont nous cherchons à hériter sont définies par nous.
Mais que se passe-t-il si l’une des classes n’est pas définie par nous, c’est-à-dire que nous ne pouvons pas changer ce dont l’une de ces classes hérite et ne peut donc pas utiliser la réponse acceptée, que se passe-t-il ensuite?
Eh bien, la réponse dépend si nous avons au moins l’une des classes définie par nous. c'est-à-dire qu'il existe une classe A
parmi la liste des classes dont nous aimerions hériter, où A
est créé par nous.
En plus de la réponse déjà acceptée, je propose 3 instances supplémentaires de ce problème d'héritage multiple et des solutions possibles pour chacune d'elles.
Ok, vous voulez qu'une classe C
étende des classes, A
et B
, où B
est une classe définie ailleurs, mais A
est défini par nous. Ce que nous pouvons faire avec ceci est de transformer A
en une interface, alors la classe C
peut implémenter A
tout en étendant B
.
class A {}
class B {} // Some external class
class C {}
Se transforme en
interface A {}
class AImpl implements A {}
class B {} // Some external class
class C extends B implements A
Supposons maintenant que vous ayez plus de deux classes à hériter, et bien la même idée est toujours valable: toutes les classes sauf une doivent être définies par nous. Donc, supposons que la classe A
hérite des classes suivantes, B
, C
, ... X
où X
est une classe qui nous est extérieure, c'est-à-dire définie ailleurs. Nous appliquons la même idée de transformer toutes les autres classes sauf la dernière en une interface, nous pouvons alors avoir:
interface B {}
class BImpl implements B {}
interface C {}
class CImpl implements C {}
...
class X {}
class A extends X implements B, C, ...
Enfin, il existe également le cas où vous ne pouvez hériter que d'un groupe de classes, mais aucune d'entre elles n'est définie par vous. C'est un peu plus compliqué, mais c'est faisable en utilisant delegation . La délégation permet à une classe A
de prétendre être une autre classe B
mais tous les appels sur A
à une méthode publique définie dans B
, délèguent en fait cet appel à un objet de type B
et le résultat est renvoyé. Cela rend la classe A
ce que j’appellerais un Fat class
Comment cela aide-t-il?
Eh bien c'est simple. Vous créez une interface qui spécifie les méthodes publiques dans les classes externes que vous souhaitez utiliser, ainsi que les méthodes dans la nouvelle classe que vous créez, puis vous demandez à votre nouvelle classe d'implémenter cette interface. Cela peut paraître déroutant, alors laissez-moi mieux vous expliquer.
Au départ, nous avons les classes externes suivantes B
, C
, D
, ..., X
et nous voulons que notre nouvelle classe A
hérite de toutes ces classes.
class B {
public void foo() {}
}
class C {
public void bar() {}
}
class D {
public void fooFoo() {}
}
...
class X {
public String fooBar() {}
}
Ensuite, nous créons une interface A
qui expose les méthodes publiques qui étaient auparavant dans la classe A ainsi que les méthodes publiques des classes ci-dessus.
interface A {
void doSomething(); // previously defined in A
String fooBar(); // from class X
void fooFoo(); // from class D
void bar(); // from class C
void foo(); // from class B
}
Enfin, nous créons une classe AImpl
qui implémente l'interface A
.
class AImpl implements A {
// It needs instances of the other classes, so those should be
// part of the constructor
public AImpl(B b, C c, D d, X x) {}
... // define the methods within the interface
}
Et voila! C'est en quelque sorte un pseudo-héritage, car un objet de type A
n'est pas un descendant strict des classes externes avec lesquelles nous avons commencé, mais expose plutôt une interface qui définit les mêmes méthodes que dans ces classes.
Vous vous demandez peut-être pourquoi nous n'avons pas simplement créé une classe définissant les méthodes que nous aimerions utiliser plutôt que de définir une interface. c'est-à-dire pourquoi n'avons-nous pas simplement une classe A
contenant les méthodes publiques des classes dont nous aimerions hériter? Ceci est fait afin de réduire le couplage . Nous ne voulons pas que les classes qui utilisent A
dépendent trop de la classe A
(car les classes ont tendance à beaucoup changer), mais plutôt que nous nous fions à la promesse donnée dans l'interface A
.
Java n'autorise pas l'extension de plusieurs classes.
Supposons que la classe C étend les classes A et B. Alors si supposons, les classes A et B ont une méthode avec le même nom (Ex: method1 ()). Considérons le code:
C obj1 = new C();
obj1.method1();
- la machine virtuelle Java ne comprendra pas à quelle méthode elle doit accéder. Parce que les classes A et B ont cette méthode. Nous mettons donc la machine virtuelle Java au centre du dilemme. C’est la raison pour laquelle l’héritage multiple est supprimé de Java. Et comme indiqué, l'implémentation de plusieurs classes résoudra ce problème.
J'espère que cela a aidé.