Herencia, composición y métodos por defecto.

Por lo general, se admite que extender las implementaciones de una interfaz a través de la herencia no es la mejor práctica, y que la composición (por ejemplo, implementar la interfaz nuevamente desde cero) es más sostenible.

Esto funciona porque el contrato de la interfaz obliga al usuario a implementar toda la funcionalidad deseada. Sin embargo, en Java 8, los métodos predeterminados proporcionan un comportamiento predeterminado que se puede anular "manualmente". Considere el siguiente ejemplo: Quiero diseñar una base de datos de usuarios, que debe tener las funcionalidades de una Lista. Elijo, por razones de eficiencia, respaldarlo con una ArrayList.

public class UserDatabase extends ArrayList<User>{}

Por lo general, esto no se consideraría una gran práctica, y uno preferiría si realmente deseara las capacidades completas de una Lista y siguiera el lema habitual de "composición sobre herencia":

public class UserDatabase implements List<User>{
  //implementation here, using an ArrayList type field, or decorator pattern, etc.
}

Sin embargo, si no está prestando atención, algunos métodos, como spliterator () no tendrán que ser anulados, ya que son métodos predeterminados de la interfaz de Lista. El problema es que el método spliterator () de List funciona mucho peor que el método spliterator () de ArrayList, que se ha optimizado para la estructura particular de una ArrayList.

Esto obliga al desarrollador a

tenga en cuenta que ArrayList tiene su propia implementación más eficiente de spliterator () y anule manualmente el método spliterator () de su propia implementación de List operder una gran cantidad de rendimiento utilizando el método predeterminado.

Entonces la pregunta es: ¿sigue siendo "tan cierto" que uno debería preferir la composición sobre la herencia en tales situaciones?

Respuestas a la pregunta(5)

Su respuesta a la pregunta