Además, me gustaría saber que si este enfoque está bien, hice los menús en clase, que es ControlMenu, y los estoy ampliando en el resto de las actividades.
No puede extender dos o más clases a la vez. La herencia múltiple no está permitida en Java.
yogsma
Respuestas:
156
Solo puede extender una sola clase. E implementar interfaces de muchas fuentes.
Extender múltiples clases no está disponible. La única solución que se me ocurre es no heredar ninguna de las clases, sino tener una variable interna de cada clase y hacer más de un proxy redirigiendo las solicitudes a su objeto al objeto al que desea que vayan.
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();}}
Esta es la mejor solución que se me ocurrió. Puede obtener la funcionalidad de ambas clases y aún así, en realidad, solo puede ser de un tipo de clase.
El inconveniente es que no puedes encajar en el molde de la clase interna usando un yeso.
Enfoque interesante, ¿qué piensan los expertos de esta técnica? Me gustaría profundizar en eso.
TechNyquist
1
¿Está bien con las convenciones?
totten
2
No se pudo lograr que la clase interna trabaje en a Fragment. Mi actividad debe extenderse Fragment, lo que significa que necesito absolutamente getView(), lo que no funcionará si está dentro de la clase interna, y el código allí es donde necesito usar el código ListActivity, por lo que no puedo extender dos veces, O hacer una clase interna en este ejemplo.
Azurespot
Esta es la mejor solución para extender clases abstractas donde necesita acceso a variables de la clase inminente.
tak3shi
45
Como todos los demás han dicho. No puedes. Sin embargo, a pesar de que las personas han dicho muchas veces a lo largo de los años que debería usar múltiples interfaces, realmente no han explicado cómo. Esperemos que esto ayude.
Digamos que sí class Fooy class Barque ambos quieren intentar extenderse a a class FooBar. Por supuesto, como dijiste, no puedes hacer:
publicclassFooBarextendsFoo,Bar
La gente ya ha entrado en las razones de esto hasta cierto punto. En cambio, escriba interfacespara ambos Fooy Barcubra todos sus métodos públicos. P.ej
Ahora, con class FooBar, se puede implementar tanto FooInterfacey BarInterfacemientras se mantiene una Fooy Barobjeto y de paso los métodos directamente a través de:
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);}//...}
La ventaja de este método es que el FooBarobjeto se ajusta a los moldes de ambos FooInterfacey BarInterface. Eso significa que esto está perfectamente bien:
Esta es una muy buena respuesta, sin embargo, veo un par de problemas que deberían abordarse con más detalle. Primero, extenderse desde dos clases existentes sería un poco más problemático y habría que superar varios obstáculos adicionales. Segundo, si la interfaz Foo y Bar tienen las mismas funciones, necesitaría tener un orden de precedencia. Extender explícitamente tu clase te obligaría a tomar esas decisiones por adelantado. Aún así, Excelente opción :) +1
The Lazy Coder
¿Qué sucede si tenemos que crear nuevas clases "con frecuencia" y hacer que cada una de esas clases implemente ambas interfaces? Entonces, tendríamos que repetir estas implementaciones repetitivas en cada clase. ¿Hay una mejor manera de hacer que una clase "implemente" dos conjuntos de comportamientos?
MasterJoe2
1
@ MasterJoe2 Para ser sincero, hace mucho tiempo que no uso Java (me detuve cuando escribí esta respuesta). Una de las razones por las que lo evito hoy en día es el problema que planteas. Una corazonada para una dirección que posiblemente podría investigar, es escribir una clase abstracta que implemente ambas interfaces y ampliarla. Sin embargo, no tengo ni idea de si eso es Java válido, y creo que terminarás con el mismo problema original cuando quieras hacer cambios en la clase de implementación en el futuro. Lo siento, no puedo ser más de ayuda.
SCB
37
Querrás usar interfaces. En general, la herencia múltiple es mala debido al problema del diamante:
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 ++ y otros tienen un par de formas de resolver esto, p. Ej.
Nunca entendí por qué el problema del diamante es en realidad un problema que impide la herencia múltiple. ¿Por qué el compilador no puede simplemente quejarse si hay métodos en conflicto con el mismo nombre?
pete
1
Para compiladores suficientemente inteligentes, no lo es. Es posible resolverlo en el nivel del compilador, y de hecho C ++ lo hace con virtual class. Hacerlo viene con muchas advertencias y advertencias, tanto para el compilador como para el desarrollador.
David Souther
1
¿Qué tal los mismos métodos predeterminados en dos interfaces? Ese es otro ejemplo del problema del diamante, que Java puede manejar.
No puede regresar "bar"o "baz"con el tipo de método de void. De todos modos, buena explicación xD
xdevs23
22
Sí, como todos los demás escribieron, no se puede hacer herencia múltiple en Java. Si tiene dos clases de las cuales le gustaría usar el código, normalmente solo subclase una (por ejemplo, clase A). Para la clase B, abstraes los métodos importantes de la misma en una interfaz BInterface(nombre feo, pero entiendes la idea), luego dices Main extends A implements BInterface. En el interior, puede crear una instancia de un objeto de clase Be implementar todos los métodos BInterfacellamando a las funciones correspondientes de B.
Esto cambia la relación "es-a" a una relación "tiene-a" como su Mainahora es un A, pero tiene un B. Dependiendo de su caso de uso, incluso puede hacer que ese cambio sea explícito eliminando el BInterfacede su Aclase y en su lugar proporcionar un método para acceder a su objeto B directamente.
aww por qué el downvote? No estaba siendo media, sólo creo que podía permitirse el lujo de leer un poco y pensar en el problema por su cuenta antes de que construimos sus clases para él
slandau
6
Java no admite herencia múltiple, pero puede intentar implementar dos o más interfaces.
Como otra alternativa, tal vez pueda usar una interfaz con una implementación predeterminada de un método. Eso depende, por supuesto, de lo que quieras hacer.
Por ejemplo, puede crear una clase abstracta y una interfaz:
publicabstractclassFatherClass{abstractvoid methodInherit(){//... do something}}publicinterfaceInterfaceWithDefaultsMethods{defaultvoid anotherMethod(){//... do something//... maybe a method with a callable for call another function.}}
Entonces, después de eso, puede extender e implementar ambas clases y usar ambos métodos.
Parallaxory ParallaxControllerson desconocidos, así que supongo que no son clases SDK. Entonces esto no funciona para mí (y, por lo tanto, esta respuesta muestra errores). ¿Qué es ParallaxController? ¿Es esta una dependencia específica? Por favor explique
Zoe
1
Los creadores de Java decidieron que los problemas de la herencia múltiple superan los beneficios, por lo que no incluyeron la herencia múltiple. Puede leer sobre uno de los mayores problemas de herencia múltiple (el problema del doble diamante) aquí .
Los dos conceptos más similares son la implementación de la interfaz y la inclusión de objetos de otras clases como miembros de la clase actual. El uso de métodos predeterminados en las interfaces es casi exactamente lo mismo que la herencia múltiple, sin embargo, se considera una mala práctica usar una interfaz solo con métodos predeterminados.
Respuestas:
Solo puede extender una sola clase. E implementar interfaces de muchas fuentes.
Extender múltiples clases no está disponible. La única solución que se me ocurre es no heredar ninguna de las clases, sino tener una variable interna de cada clase y hacer más de un proxy redirigiendo las solicitudes a su objeto al objeto al que desea que vayan.
Esta es la mejor solución que se me ocurrió. Puede obtener la funcionalidad de ambas clases y aún así, en realidad, solo puede ser de un tipo de clase.
El inconveniente es que no puedes encajar en el molde de la clase interna usando un yeso.
fuente
¿Por qué no utilizar una clase interna (anidamiento)
fuente
Fragment
. Mi actividad debe extenderseFragment
, lo que significa que necesito absolutamentegetView()
, lo que no funcionará si está dentro de la clase interna, y el código allí es donde necesito usar el códigoListActivity
, por lo que no puedo extender dos veces, O hacer una clase interna en este ejemplo.Como todos los demás han dicho. No puedes. Sin embargo, a pesar de que las personas han dicho muchas veces a lo largo de los años que debería usar múltiples interfaces, realmente no han explicado cómo. Esperemos que esto ayude.
Digamos que sí
class Foo
yclass Bar
que ambos quieren intentar extenderse a aclass FooBar
. Por supuesto, como dijiste, no puedes hacer:La gente ya ha entrado en las razones de esto hasta cierto punto. En cambio, escriba
interfaces
para ambosFoo
yBar
cubra todos sus métodos públicos. P.ejY ahora crea
Foo
eBar
implementa las interfaces relativas:Ahora, con
class FooBar
, se puede implementar tantoFooInterface
yBarInterface
mientras se mantiene unaFoo
yBar
objeto y de paso los métodos directamente a través de:La ventaja de este método es que el
FooBar
objeto se ajusta a los moldes de ambosFooInterface
yBarInterface
. Eso significa que esto está perfectamente bien:Espero que esto aclare cómo usar interfaces en lugar de múltiples extensiones. Incluso si llego unos años tarde.
fuente
Querrás usar interfaces. En general, la herencia múltiple es mala debido al problema del diamante:
C ++ y otros tienen un par de formas de resolver esto, p. Ej.
pero Java solo usa interfaces.
Los senderos de Java tienen una excelente introducción a las interfaces: http://download.oracle.com/javase/tutorial/java/concepts/interface.html Probablemente quieras seguir eso antes de sumergirte en los matices de la API de Android.
fuente
virtual class
. Hacerlo viene con muchas advertencias y advertencias, tanto para el compilador como para el desarrollador.super
desde un método heredado. Bueno, puede, pero debe especificar el método de interfaz para invocar (y debe usar la palabra clavedefault
en la implementación de la interfaz) . Un ejemplo es:MyIFace.super.foo()
donde MyIFace es una interfaz. Como puede ver, el método de interfaz para ejecutar está definido y evita el problema del diamante por completo. Si extiendeMyClass1
yMyClass2
, ambas clases tienen unfoo()
, y llama,super.foo()
entonces el Compilador es lanzado por el Problema Diamante."bar"
o"baz"
con el tipo de método devoid
. De todos modos, buena explicación xDSí, como todos los demás escribieron, no se puede hacer herencia múltiple en Java. Si tiene dos clases de las cuales le gustaría usar el código, normalmente solo subclase una (por ejemplo, clase
A
). Para la claseB
, abstraes los métodos importantes de la misma en una interfazBInterface
(nombre feo, pero entiendes la idea), luego dicesMain extends A implements BInterface
. En el interior, puede crear una instancia de un objeto de claseB
e implementar todos los métodosBInterface
llamando a las funciones correspondientes deB
.Esto cambia la relación "es-a" a una relación "tiene-a" como su
Main
ahora es unA
, pero tiene unB
. Dependiendo de su caso de uso, incluso puede hacer que ese cambio sea explícito eliminando elBInterface
de suA
clase y en su lugar proporcionar un método para acceder a su objeto B directamente.fuente
Haz una interfaz. Java no tiene herencia múltiple.
http://csis.pace.edu/~bergin/patterns/multipleinheritance.html
fuente
Java no admite herencia múltiple, pero puede intentar implementar dos o más interfaces.
fuente
Si. Slandau tiene razón. Java no permite extender desde varias clases.
Lo que quieres es probablemente
public class Main extends ListActivity implements ControlMenu
. Supongo que estás tratando de hacer una lista.Espero que ayude.
fuente
Como otra alternativa, tal vez pueda usar una interfaz con una implementación predeterminada de un método. Eso depende, por supuesto, de lo que quieras hacer.
Por ejemplo, puede crear una clase abstracta y una interfaz:
Entonces, después de eso, puede extender e implementar ambas clases y usar ambos métodos.
Espero que esto te ayude...
fuente
Extender desde múltiples clases no está permitido en Java ... ¡para evitar el Diamante mortal de la muerte !
fuente
es posible
fuente
Parallaxor
yParallaxController
son desconocidos, así que supongo que no son clases SDK. Entonces esto no funciona para mí (y, por lo tanto, esta respuesta muestra errores). ¿Qué es ParallaxController? ¿Es esta una dependencia específica? Por favor expliqueLos creadores de Java decidieron que los problemas de la herencia múltiple superan los beneficios, por lo que no incluyeron la herencia múltiple. Puede leer sobre uno de los mayores problemas de herencia múltiple (el problema del doble diamante) aquí .
Los dos conceptos más similares son la implementación de la interfaz y la inclusión de objetos de otras clases como miembros de la clase actual. El uso de métodos predeterminados en las interfaces es casi exactamente lo mismo que la herencia múltiple, sin embargo, se considera una mala práctica usar una interfaz solo con métodos predeterminados.
fuente
no puedes hacer herencia múltiple en java. considere usar interfaces:
o clases internas:
fuente