java - tipos - La ambigüedad de herencia múltiple con interfaz
interface java (6)
Todos conocemos el problema del diamante con respecto a la herencia múltiple.
A
/ /
B C
/ /
D
Este problema describe una situación ambigua para la clase D
Si la clase A
tiene un método y ambos / cualquiera de B
y / o C
anulan el método, ¿qué versión del método anula D
?
¿Es este problema también aplicable para interfaces en Java? Si no, ¿cómo las interfaces de Java superan este problema?
Con los métodos predeterminados en la interfaz introducida en Java 8, pueden surgir problemas relacionados con la herencia múltiple, existen 3 escenarios:
1- Si la clase de implementación anula el método predeterminado y proporciona su propia funcionalidad para el método predeterminado, entonces el método de la clase tiene prioridad sobre los métodos predeterminados de la interfaz.
2-Cuando la clase implementa ambas interfaces y ambas tienen el mismo método predeterminado, también la clase no está anulando ese método, entonces se lanzará el error.
3-En el caso de que una interfaz extienda otra interfaz y ambas tengan el mismo método predeterminado, el método predeterminado heredado de la interfaz tendrá prioridad.
Lea más sobre esto here .
El problema de diamante solo se aplica a la herencia de implementación (se extends
en todas las versiones de Java anteriores a Java 8). No se aplica a la herencia de API ( implements
en todas las versiones de Java antes de Java 8).
Dado que los métodos de interfaz con firmas de tipo coincidente son compatibles, no hay problema de diamante si hereda la misma firma de método dos veces: las firmas de método coincidente simplemente se unen en su lugar. (Y si las firmas de tipo no son las mismas, tampoco tiene el problema del diamante).
En Java 7 y versiones anteriores, la única forma de heredar el código de implementación era a través de la palabra clave extended, que se restringe a un padre como máximo. Por lo tanto, no hay herencia de implementación múltiple y el problema de diamante no existe.
Java 8 agrega una nueva arruga porque permite que las interfaces tengan un código de implementación. Todavía se escapa al problema de Diamond simplemente recurriendo al comportamiento anterior (sin herencia de implementación) cuando implementa varias interfaces con métodos que tienen firmas coincidentes.
Java no admite la herencia múltiple, por lo que no surge el problema del diamante. Si B & C son interfaces, entonces no hay implementación en las interfaces. Incluso si B & C anulan el método en la interfaz A (no puede ser una clase), los métodos tendrán la misma firma. No hay ambigüedad con respecto a qué implementación usar, porque no hay implementación.
Java supera este problema a pesar de que las interfaces pueden tener implementaciones de métodos predeterminadas, ya que la implementación predeterminada es inequívoca (la de la clase A
) o la situación se resuelve mediante alguna regla (cuando la clase B
o la clase C
anulan la implementación de la clase A
, vea abajo).
Cuando los supertipos de una clase o interfaz proporcionan varios métodos predeterminados con la misma firma:
- Los métodos de instancia son preferidos a los métodos predeterminados de interfaz.
- Los métodos que ya están anulados por otros candidatos se ignoran. Esta circunstancia puede surgir cuando los supertipos comparten un ancestro común .
Sin embargo, si dos o más métodos predeterminados definidos de manera independiente entran en conflicto , o un método predeterminado entra en conflicto con un método abstracto, entonces el compilador de Java produce un error de compilación. Debe anular explícitamente los métodos de supertipo . En este caso, podría invocar cualquiera de las implementaciones predeterminadas con la palabra clave super.
Vea también: ¿Cómo funciona el nuevo modelo de interfaz por defecto de Java 8 ''(incl. Diamante, herencia múltiple y prioridad)?
Las interfaces tienen declaraciones ficticias y no tendrán implementaciones, por lo que no hay problema de ambigüedad.
Para agregar a las respuestas existentes sobre la herencia múltiple de Java8 con interfaces (también conocida como Java aún evita el problema de diamante):
Hay tres reglas a seguir:
Una clase siempre gana . La implementación del método propio de la clase tiene prioridad sobre los métodos predeterminados en Interfaces.
Si la clase no tiene ninguna: gana la interfaz más específica
- Si lo anterior no es el caso, la clase heredada debe indicar explícitamente qué implementación de método está utilizando (de lo contrario no se compilará)