web-dev-qa-db-fra.com

Classe étendant plus d'une classe Java?

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? 

Héritage TransformGroup

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?

20
Bujanca Mihai

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.

50
Kevin Bowersox

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
4
Puce

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
4
András Tóth

Il n'y a pas de concept d'héritage multiple en Java. Seules plusieurs interfaces peuvent être implémentées.

3
Aashray

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.

3
amitguptageek

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.

3
Rais Alam

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

2
The Reader

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{
}
2
Biswajit

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.

Type d'héritage 1

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

Héritage type 2

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, ... XX 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, ...

Type d'héritage 3

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.

1
smac89

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é.

0
Srekk