¿Por qué no hay herencia múltiple en Java, pero se permite implementar múltiples interfaces?


Java no permite la herencia múltiple, pero permite implementar múltiples interfaces. ¿Por qué?

Author: Ravindra babu, 2010-03-25

15 answers

Porque las interfaces solo especifican lo que está haciendo la clase, no cómo lo está haciendo.

El problema con la herencia múltiple es que dos clases pueden definir diferentes formas de hacer lo mismo, y la subclase no puede elegir cuál elegir.

 189
Author: Bozho,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-25 12:43:02

Uno de mis instructores universitarios me lo explicó de esta manera:

Supongamos que tengo una clase, que es una tostadora, y otra clase, que es una bomba nuclear. Ambos podrían tener una configuración de "oscuridad". Ambos tienen un método on (). (Uno tiene un off (), el otro no.) Si quiero crear una clase que es una subclase de ambos these...as puedes ver, este es un problema que realmente podría explotar en mi cara aquí.

Así que uno de los principales problemas es que si tienes dos las clases principales, pueden tener diferentes implementaciones de la misma característica, o posiblemente dos características diferentes con el mismo nombre, como en el ejemplo de mi instructor. Entonces usted tiene que lidiar con decidir cuál su subclase va a utilizar. Hay maneras de manejar esto, ciertamente - C++ lo hace - pero los diseñadores de Java sintieron que esto haría las cosas demasiado complicadas.

Con una interfaz, sin embargo, estás describiendo algo que la clase es capaz de hacer, en lugar de pedir prestado el método de otra clase para hacer algo. Es mucho menos probable que varias interfaces causen conflictos complicados que deban resolverse que varias clases principales.

 84
Author: Syntactic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-25 13:04:37

Debido a que la herencia se usa en exceso incluso cuando no puede decir "oye, ese método parece útil, extenderé esa clase también".

public class MyGodClass extends AppDomainObject, HttpServlet, MouseAdapter, 
             AbstractTableModel, AbstractListModel, AbstractList, AbstractMap, ...
 22
Author: Michael Borgwardt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-25 12:50:45

Implementar múltiples interfaces es muy útil y no causa muchos problemas a los implementadores de lenguaje ni a los programadores. Así que está permitido. La herencia múltiple, aunque también es útil, puede causar graves problemas a los usuarios (temido diamante de la muerte ). Y la mayoría de las cosas que haces con herencia múltiple también se pueden hacer por composición o usando clases internas. Así que la herencia múltiple está prohibida por traer más problemas que ganancias.

 6
Author: Tadeusz Kopec,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-25 13:00:09

Por la misma razón, C# no permite la herencia múltiple, pero le permite implementar múltiples interfaces.

La lección aprendida de C++ con herencia múltiple fue que condujo a más problemas de los que valía la pena.

Una interfaz es un contrato de cosas que tu clase tiene que implementar. No se obtiene ninguna funcionalidad de la interfaz. Herencia le permite heredar la funcionalidad de una clase padre (y en herencia múltiple, que puede obtener extremadamente confuso).

Permitir múltiples interfaces le permite usar Patrones de diseño (como el Adaptador) para resolver los mismos tipos de problemas que puede resolver usando herencia múltiple, pero de una manera mucho más confiable y predecible.

 3
Author: Justin Niessner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-25 12:47:46

Java admite herencia múltiple solo a través de interfaces. Una clase puede implementar cualquier número de interfaces, pero puede extender solo una clase.

La herencia múltiple no es compatible porque conduce a un problema mortal de diamantes. Sin embargo, se puede resolver, pero conduce a un sistema complejo, por lo que la herencia múltiple ha sido descartada por los fundadores de Java.

En un libro blanco titulado "Java: una visión general" por James Gosling en febrero de 1995 (enlace) da una idea de por qué múltiples la herencia no se admite en Java.

Según Gosling:

" JAVA omite muchas características raras veces utilizadas, mal entendidas, confusas de C++ que en nuestra experiencia traen más dolor que beneficio. Este consiste principalmente en la sobrecarga del operador (aunque tiene método de sobrecarga), herencia múltiple, y automática extensa coacción."

 3
Author: Praveen Kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-28 07:33:23

Se dice que el estado de los objetos se refiere con respecto a los campos en él y se volvería ambiguo si se heredaran demasiadas clases. Aquí está el enlace

Http://docs.oracle.com/javase/tutorial/java/IandI/multipleinheritance.html

 2
Author: Karthik GVD,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-13 15:29:02

Puede encontrar una respuesta precisa para esta consulta en la página de documentación de oracle sobre herencia múltiple

  1. Herencia múltiple del estado: Capacidad de heredar campos de múltiples clases

    Una razón por la que el lenguaje de programación Java no le permite extender más de una clase es para evitar los problemas de herencia múltiple de estado, que es la capacidad de heredar campos de múltiples clases

    Si se permite la herencia múltiple y cuando crea un objeto instanciando esa clase, ese objeto heredará campos de todas las superclases de la clase. Causará dos problemas.

    1. ¿Qué pasa si los métodos o constructores de diferentes superclases instancian el mismo campo?
    2. ¿Qué método o constructor tendrá prioridad?
  2. Herencia múltiple de la implementación: Capacidad de heredar definiciones de métodos de múltiples clases

    Problemas con este enfoque: name conflicts y ambiguity. Si una subclase y una superclase contienen el mismo nombre de método (y firma), el compilador no puede determinar qué versión invocar.

    Pero java soporta este tipo de herencia múltiple con métodos predeterminados, que se han introducido desde el lanzamiento de Java 8. El compilador Java proporciona algunas reglas para determinar qué método predeterminado usa una clase en particular.

    Refiérase a continuación SE post para más detalles sobre la resolución del problema de los diamantes:

    ¿Cuáles son las diferencias entre las clases abstractas y las interfaces en Java 8?

  3. la herencia Múltiple de tipo: Capacidad de una clase para implementar más de una interfaz.

    Dado que la interfaz no contiene campos mutables, no tiene que preocuparse por los problemas que resultan de la herencia múltiple de estado aquí.

 2
Author: Ravindra babu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 10:31:17

Dado que este tema no está cerca publicaré esta respuesta, espero que esto ayude a alguien a entender por qué Java no permite la herencia múltiple.

Considere la siguiente clase:

public class Abc{

    public void doSomething(){

    }

}

En este caso la clase Abc no extiende nada ¿correcto? No tan rápido, esta clase implícita extiende la clase Objeto, clase base que permite que todo funcione en java. Todo es un objeto.

Si intentas usar la clase anterior verás que tu IDE te permite usar métodos like: equals(Object o), toString(), etc, pero no declaraste esos métodos, vinieron de la clase base Object

Puedes intentar:

public class Abc extends String{

    public void doSomething(){

    }

}

Esto está bien, porque tu clase no extenderá implícitamente Object sino que extenderá String porque tú lo dijiste. Considere el siguiente cambio:

public class Abc{

    public void doSomething(){

    }

    @Override
    public String toString(){
        return "hello";
    }

}

Ahora tu clase siempre devolverá "hola" si llamas a toString().

Ahora imagine la siguiente clase:

public class Flyer{

    public void makeFly(){

    }

}

public class Bird extends Abc, Flyer{

    public void doAnotherThing(){

    }

}

De nuevo la clase Flyer implícito extiende Objeto que tiene el method toString(), cualquier clase tendrá este método ya que todos se extienden Object indirectamente, por lo tanto, si llamas toString() desde Bird, ¿qué toString() java tendría que usar? ¿De Abc o Flyer? Esto sucederá con cualquier clase que intente extender dos o más clases, para evitar este tipo de" colisión de métodos " construyeron la idea de interfaz, básicamente se podría pensar como una clase abstracta que no extiende Objeto indirectamente. Puesto que son abstractos tendrán para ser implementado por una clase, que es un objeto (no se puede instanciar una interfaz por sí solo, deben ser implementados por una clase), por lo que todo seguirá funcionando bien.

Para diferenciar las clases de las interfaces, la palabra clave implements se reservó solo para las interfaces.

Puede implementar cualquier interfaz que desee en la misma clase ya que no extiende nada por defecto (pero puede crear una interfaz que extienda otra interfaz, pero una vez más, la interfaz "padre" no extendería Objeto"), por lo que una interfaz es solo una interfaz y no sufrirán de "métodos firma colissions", si lo hacen el compilador lanzará una advertencia a usted y usted solo tendrá que cambiar la firma del método para arreglarlo (firma = nombre del método + parámetros + tipo de retorno).

public interface Flyer{

    public void makeFly(); // <- method without implementation

}

public class Bird extends Abc implements Flyer{

    public void doAnotherThing(){

    }

    @Override
    public void makeFly(){ // <- implementation of Flyer interface

    }

    // Flyer does not have toString() method or any method from class Object, 
    // no method signature collision will happen here

}
 1
Author: Murillo Henrique,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-11 05:20:59

Porque una interfaz es solo un contrato. Y una clase es realmente un contenedor de datos.

 0
Author: Snake,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-25 12:42:31

Tomemos por ejemplo el caso donde la Clase A tiene un método getSomething y la clase B tiene un método getSomething y la clase C extiende A y B. ¿Qué pasaría si alguien llamara a C. getSomething? No hay forma de determinar a qué método llamar.

Las interfaces básicamente solo especifican qué métodos debe contener una clase de implementación. Una clase que implementa múltiples interfaces solo significa que la clase tiene que implementar los métodos de todas esas interfaces. Whci no daría lugar a ningún problema como se describió anteriormente.

 0
Author: John Kane,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-20 19:10:34

Considere un escenario donde Test1, Test2 y Test3 son tres clases. La clase Test3 hereda las clases Test2 y Test1. Si las clases Test1 y Test2 tienen el mismo método y lo llamas desde el objeto de clase hijo, habrá ambigüedad para llamar al método de la clase Test1 o Test2, pero no hay tal ambigüedad para la interfaz, ya que en la interfaz no hay ninguna implementación.

 0
Author: Nikhil Kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-21 09:41:57

Java no admite herencia múltiple, multipath y herencia híbrida debido a la ambigüedad problema:

 Scenario for multiple inheritance: Let us take class A , class B , class C. class A has alphabet(); method , class B has also alphabet(); method. Now class C extends A, B and we are creating object to the subclass i.e., class C , so  C ob = new C(); Then if you want call those methods ob.alphabet(); which class method takes ? is class A method or class B method ?  So in the JVM level ambiguity problem occurred. Thus Java does not support multiple inheritance.

Herencia múltiple

Enlace de Referencia: https://plus.google.com/u/0/communities/102217496457095083679

 0
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-23 14:21:59

Por ejemplo dos clases A,B que tienen el mismo método m1(). Y la clase C se extiende tanto A, B.

 class C extends A, B // for explaining purpose.

Ahora, la clase C buscará la definición de m1. Primero, buscará en la clase si no lo encontró, entonces verificará a la clase de padres. Tanto A, B tener la definición Por lo que aquí se produce ambigüedad que la definición debe elegir. Así QUE JAVA NO SOPORTA HERENCIA MÚLTIPLE.

 0
Author: Pooja Khatri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-13 06:57:40

* Esta es una respuesta simple ya que soy un principiante en Java *

Considere que hay tres clases X,Y y Z.

, Así que estamos heredando como X extends Y, Z Y tanto Y como Z tienen un método alphabet() con el mismo tipo de retorno y argumentos. Este método alphabet() en Y dice: mostrar el primer alfabeto y método de alfabeto Z dice: mostrar la última del alfabeto. Así que aquí viene la ambigüedad cuando alphabet() es llamado por X. Si dice mostrar primeroo último alfabeto??? Así que Java no es compatible con la herencia múltiple. En el caso de las interfaces, considerar Y y Z como interfaces. Así que ambos contendrán la declaración de método alphabet() pero no la definición. No dirá si mostrar el primer alfabeto o el último alfabeto o cualquier cosa, pero solo declarará un método alphabet(). Así que no hay razón para plantear la ambigüedad. Podemos definir el método con cualquier cosa que queramos dentro de la clase X.

Así que en una palabra, en La definición de interfaces se realiza después de la implementación, por lo que no hay confusión.

 -1
Author: AJavaLover,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-05 08:27:07