Vous ne pouvez pas prolonger deux cours ou plus à la fois. L'héritage multiple n'est pas autorisé en java.
yogsma
Réponses:
156
Vous ne pouvez étendre qu'une seule classe. Et implémentez des interfaces à partir de nombreuses sources.
L'extension de plusieurs classes n'est pas disponible. La seule solution à laquelle je peux penser n'est pas d'hériter de l'une ou l'autre des classes, mais plutôt d'avoir une variable interne de chaque classe et de faire plus d'un proxy en redirigeant les requêtes vers votre objet vers l'objet vers lequel vous voulez qu'elles aillent.
publicclassCustomActivityextendsActivity{privateAnotherClass mClass;protectedvoid onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);
mClass =newAnotherClass(this);}//Implement each method you want to use.publicString getInfoFromOtherClass(){return mClass.getInfoFromOtherClass();}}
c'est la meilleure solution que j'ai trouvée. Vous pouvez obtenir la fonctionnalité des deux classes et toujours être d'un seul type de classe.
L'inconvénient est que vous ne pouvez pas entrer dans le moule de la classe interne à l'aide d'un moulage.
Approche intéressante, que pensent les experts de cette technique? J'aimerais creuser dedans.
TechNyquist
1
Est-ce que ça va avec les conventions?
totten le
2
Impossible de faire fonctionner la classe interne dans un fichier Fragment. Mon activité doit s'étendre Fragment, ce qui signifie que j'en ai absolument besoin getView(), ce qui ne fonctionnera pas si c'est à l'intérieur de la classe interne, et le code là-dedans est l'endroit où je dois utiliser du code ListActivity, donc je ne peux pas étendre deux fois, OU faire une classe interne dans cet exemple.
Azurespot
C'est la meilleure solution pour étendre les classes abstraites où vous avez besoin d'accéder aux variables de la classe d'exécution.
tak3shi
45
Comme tout le monde l'a dit. Non, tu ne peux pas. Cependant, même si les gens ont dit à plusieurs reprises au fil des ans que vous devriez utiliser plusieurs interfaces, ils ne sont pas vraiment entrés dans la façon dont. J'espère que cela aidera.
Dites que vous l'avez fait class Fooet class Barque vous voulez tous les deux essayer de vous étendre dans un fichier class FooBar. Bien sûr, comme vous l'avez dit, vous ne pouvez pas faire:
publicclassFooBarextendsFoo,Bar
Les gens ont déjà exploré les raisons dans une certaine mesure. Au lieu de cela, écrivez interfacespour les deux Fooet en Barcouvrant toutes leurs méthodes publiques. Par exemple
Maintenant, avec class FooBar, vous pouvez mettre en œuvre à la fois FooInterfaceet BarInterfacetout en gardant un Fooet l' Barobjet et juste passer les méthodes directement à travers:
publicclassFooBarimplementsFooInterface,BarInterface{Foo myFoo;Bar myBar;// You can have the FooBar constructor require the arguments for both// the Foo and the Bar constructorspublicFooBar(int x,int y,int z){
myFoo =newFoo(x);
myBar =newBar(y, z);}// Or have the Foo and Bar objects passed right inpublicFooBar(Foo newFoo,Bar newBar){
myFoo = newFoo;
myBar = newBar;}publicvoid methodA(){
myFoo.methodA();}publicint methodB(){return myFoo.methodB();}publicint methodC(int i){return myBar.methodC(i);}//...}
Le bonus de cette méthode est que l' FooBarobjet s'adapte aux moules des deux FooInterfaceet BarInterface. Cela signifie que c'est parfaitement bien:
C'est une très bonne réponse, mais je vois quelques problèmes qui devraient être abordés plus en détail. Premièrement, étendre à partir de deux classes existantes serait un peu plus problématique et il y aurait un certain nombre d'obstacles supplémentaires à franchir, Deuxièmement, si les interfaces Foo et Bar avaient toutes les deux les mêmes fonctions, vous auriez besoin d'un ordre de priorité. Étendre explicitement votre classe vous obligerait à prendre ces décisions dès le départ. Encore, excellente option :) +1
The Lazy Coder
Et si nous devions créer de nouvelles classes "fréquemment" et faire en sorte que chacune de ces classes implémente les deux interfaces? Ensuite, nous devrons répéter ces implémentations standard dans chaque classe. Existe-t-il une meilleure façon de faire en sorte qu'une classe «implémente» deux ensembles de comportements?
MasterJoe2
1
@ MasterJoe2 Pour être honnête, je n'ai pas beaucoup utilisé Java depuis un moment maintenant (je me suis arrêté à peu près au moment où j'ai écrit cette réponse). L'une des raisons pour lesquelles j'évite cela de nos jours est la question même que vous soulevez. Une intuition pour une direction que vous pourriez éventuellement étudier est l'écriture d'une classe abstraite qui implémente les deux interfaces et l'étend. Cependant, je n'ai aucune idée si c'est Java valide, et je pense que vous vous retrouverez avec le même problème d'origine lorsque vous voudrez apporter des modifications à la classe d'implémentation à l'avenir. Désolé, je ne peux pas être plus d'une aide.
SCB
37
Vous voudrez utiliser des interfaces. Généralement, l'héritage multiple est mauvais à cause du problème du diamant:
abstractclass A {abstract string foo();}class B extends A {
string foo (){return"bar";}}class C extends A {
string foo(){return"baz";}}class D extends B, C {
string foo(){returnsuper.foo();}//What do I do? Which method should I call?}
C ++ et d'autres ont plusieurs façons de résoudre ce problème, par exemple
Je n'ai jamais compris pourquoi le problème du diamant est en fait un problème qui empêche l'héritage multiple. Pourquoi le compilateur ne peut-il pas simplement se plaindre s'il existe des méthodes en conflit avec le même nom?
pete
1
Pour les compilateurs suffisamment intelligents, ce n'est pas le cas. Le résoudre au niveau du compilateur est possible, et en effet C ++ le fait avec virtual class. Cela s'accompagne de nombreux avertissements et mises en garde, à la fois pour le compilateur et le développeur.
David Souther
1
Que diriez-vous des mêmes méthodes par défaut dans deux interfaces? C'est un autre exemple du problème du diamant, que java peut gérer.
Vous ne pouvez pas retourner "bar"ou "baz"avec le type de méthode void. Quoi qu'il en soit, bonne explication xD
xdevs23
22
Oui, comme tout le monde l'a écrit, vous ne pouvez pas faire d'héritage multiple en Java. Si vous avez deux classes à partir desquelles vous souhaitez utiliser du code, vous en sous-classerez généralement une (disons classe A). Pour la classe B, vous résumez les méthodes importantes de celui-ci dans une interface BInterface(nom moche, mais vous avez l'idée), puis dites Main extends A implements BInterface. À l'intérieur, vous pouvez instancier un objet de classe Bet implémenter toutes les méthodes de BInterfaceen appelant les fonctions correspondantes de B.
Cela change la relation «est-un» en une relation «a-a», car vous Mainêtes maintenant un A, mais a un B. Selon votre cas d'utilisation, vous pouvez même rendre cette modification explicite en supprimant le BInterfacede votre Aclasse et en fournissant à la place une méthode pour accéder directement à votre objet B.
aww pourquoi le vote négatif? Je n'étais pas méchant, je pense juste qu'il pouvait se permettre de faire un peu de lecture et de réfléchir au problème par lui-même avant de construire ses cours pour lui
slandau
6
Java ne prend pas en charge l'héritage multiple, mais vous pouvez essayer d'implémenter deux interfaces ou plus.
Comme une autre alternative, vous pouvez peut-être utiliser une interface avec une implémentation par défaut d'une méthode. Cela dépend bien sûr de ce que vous voulez faire.
Par exemple, vous pouvez créer une classe abstraite et une interface:
publicabstractclassFatherClass{abstractvoid methodInherit(){//... do something}}publicinterfaceInterfaceWithDefaultsMethods{defaultvoid anotherMethod(){//... do something//... maybe a method with a callable for call another function.}}
Ainsi, après cela, vous pouvez étendre et implémenter les deux classes et utiliser les deux méthodes.
Parallaxoret ParallaxControllersont inconnus, donc je suppose qu'ils ne sont pas des classes SDK. Donc, cela ne fonctionne pas pour moi (et donc cette réponse montre des erreurs). Qu'est-ce que ParallaxController? Est-ce une dépendance spécifique? Veuillez préciser
Zoe
1
Les créateurs de java ont décidé que les problèmes d'héritage multiple l'emportaient sur les avantages, ils n'incluaient donc pas l'héritage multiple. Vous pouvez en savoir plus sur l'un des plus gros problèmes d'héritage multiple (le problème du double diamant) ici .
Les deux concepts les plus similaires sont l'implémentation d'interface et l'inclusion d'objets d'autres classes en tant que membres de la classe actuelle. L'utilisation de méthodes par défaut dans les interfaces est presque exactement la même chose que l'héritage multiple, mais il est considéré comme une mauvaise pratique d'utiliser une interface avec uniquement des méthodes par défaut.
Réponses:
Vous ne pouvez étendre qu'une seule classe. Et implémentez des interfaces à partir de nombreuses sources.
L'extension de plusieurs classes n'est pas disponible. La seule solution à laquelle je peux penser n'est pas d'hériter de l'une ou l'autre des classes, mais plutôt d'avoir une variable interne de chaque classe et de faire plus d'un proxy en redirigeant les requêtes vers votre objet vers l'objet vers lequel vous voulez qu'elles aillent.
c'est la meilleure solution que j'ai trouvée. Vous pouvez obtenir la fonctionnalité des deux classes et toujours être d'un seul type de classe.
L'inconvénient est que vous ne pouvez pas entrer dans le moule de la classe interne à l'aide d'un moulage.
la source
Pourquoi ne pas utiliser une classe intérieure (imbrication)
la source
Fragment
. Mon activité doit s'étendreFragment
, ce qui signifie que j'en ai absolument besoingetView()
, ce qui ne fonctionnera pas si c'est à l'intérieur de la classe interne, et le code là-dedans est l'endroit où je dois utiliser du codeListActivity
, donc je ne peux pas étendre deux fois, OU faire une classe interne dans cet exemple.Comme tout le monde l'a dit. Non, tu ne peux pas. Cependant, même si les gens ont dit à plusieurs reprises au fil des ans que vous devriez utiliser plusieurs interfaces, ils ne sont pas vraiment entrés dans la façon dont. J'espère que cela aidera.
Dites que vous l'avez fait
class Foo
etclass Bar
que vous voulez tous les deux essayer de vous étendre dans un fichierclass FooBar
. Bien sûr, comme vous l'avez dit, vous ne pouvez pas faire:Les gens ont déjà exploré les raisons dans une certaine mesure. Au lieu de cela, écrivez
interfaces
pour les deuxFoo
et enBar
couvrant toutes leurs méthodes publiques. Par exempleEt maintenant, créez
Foo
etBar
implémentez les interfaces relatives:Maintenant, avec
class FooBar
, vous pouvez mettre en œuvre à la foisFooInterface
etBarInterface
tout en gardant unFoo
et l'Bar
objet et juste passer les méthodes directement à travers:Le bonus de cette méthode est que l'
FooBar
objet s'adapte aux moules des deuxFooInterface
etBarInterface
. Cela signifie que c'est parfaitement bien:J'espère que cela clarifie comment utiliser les interfaces au lieu de plusieurs extensions. Même si j'ai quelques années de retard.
la source
Vous voudrez utiliser des interfaces. Généralement, l'héritage multiple est mauvais à cause du problème du diamant:
C ++ et d'autres ont plusieurs façons de résoudre ce problème, par exemple
mais Java n'utilise que des interfaces.
Les Java Trails ont une excellente introduction sur les interfaces: http://download.oracle.com/javase/tutorial/java/concepts/interface.html Vous voudrez probablement suivre cela avant de plonger dans les nuances de l'API Android.
la source
virtual class
. Cela s'accompagne de nombreux avertissements et mises en garde, à la fois pour le compilateur et le développeur.super
partir d'une méthode héritière. Eh bien, vous pouvez, mais vous devez spécifier la méthode d'interface à invoquer (et elle doit utiliser le mot-clédefault
dans l'implémentation de l'interface) . Un exemple est:MyIFace.super.foo()
où MyIFace est une interface. Comme vous pouvez le voir, la méthode d'interface à exécuter est définie et évite complètement le problème du diamant. Si vous étendezMyClass1
etMyClass2
, les deux classes ont unfoo()
appel et,super.foo()
le compilateur est lancé par le problème Diamond."bar"
ou"baz"
avec le type de méthodevoid
. Quoi qu'il en soit, bonne explication xDOui, comme tout le monde l'a écrit, vous ne pouvez pas faire d'héritage multiple en Java. Si vous avez deux classes à partir desquelles vous souhaitez utiliser du code, vous en sous-classerez généralement une (disons classe
A
). Pour la classeB
, vous résumez les méthodes importantes de celui-ci dans une interfaceBInterface
(nom moche, mais vous avez l'idée), puis ditesMain extends A implements BInterface
. À l'intérieur, vous pouvez instancier un objet de classeB
et implémenter toutes les méthodes deBInterface
en appelant les fonctions correspondantes deB
.Cela change la relation «est-un» en une relation «a-a», car vous
Main
êtes maintenant unA
, mais a unB
. Selon votre cas d'utilisation, vous pouvez même rendre cette modification explicite en supprimant leBInterface
de votreA
classe et en fournissant à la place une méthode pour accéder directement à votre objet B.la source
Créez une interface. Java n'a pas d'héritage multiple.
http://csis.pace.edu/~bergin/patterns/multipleinheritance.html
la source
Java ne prend pas en charge l'héritage multiple, mais vous pouvez essayer d'implémenter deux interfaces ou plus.
la source
Oui. slandau a raison. Java n'autorise pas l'extension de plusieurs classes.
Ce que vous voulez, c'est probablement
public class Main extends ListActivity implements ControlMenu
. Je suppose que vous essayez de faire une liste.J'espère que cela pourra aider.
la source
Comme une autre alternative, vous pouvez peut-être utiliser une interface avec une implémentation par défaut d'une méthode. Cela dépend bien sûr de ce que vous voulez faire.
Par exemple, vous pouvez créer une classe abstraite et une interface:
Ainsi, après cela, vous pouvez étendre et implémenter les deux classes et utiliser les deux méthodes.
J'espère que cela vous aidera ...
la source
L'extension à partir de plusieurs classes n'est pas autorisée en java .. pour empêcher Deadly Diamond of Death !
la source
c'est possible
la source
Parallaxor
etParallaxController
sont inconnus, donc je suppose qu'ils ne sont pas des classes SDK. Donc, cela ne fonctionne pas pour moi (et donc cette réponse montre des erreurs). Qu'est-ce que ParallaxController? Est-ce une dépendance spécifique? Veuillez préciserLes créateurs de java ont décidé que les problèmes d'héritage multiple l'emportaient sur les avantages, ils n'incluaient donc pas l'héritage multiple. Vous pouvez en savoir plus sur l'un des plus gros problèmes d'héritage multiple (le problème du double diamant) ici .
Les deux concepts les plus similaires sont l'implémentation d'interface et l'inclusion d'objets d'autres classes en tant que membres de la classe actuelle. L'utilisation de méthodes par défaut dans les interfaces est presque exactement la même chose que l'héritage multiple, mais il est considéré comme une mauvaise pratique d'utiliser une interface avec uniquement des méthodes par défaut.
la source
vous ne pouvez pas faire d'héritage multiple en java. envisagez d'utiliser des interfaces:
ou classes internes:
la source