¿Es posible la OOP y evitar por completo la herencia de implementación?
Elegiré Java como ejemplo, la mayoría de la gente lo sabe, aunque todos los demás lenguajes OO también funcionaban.
Java, como muchos otros lenguajes, tiene herencia de interfaz y herencia de implementación. P.ej. una clase Java puede heredar de otro y todos los métodos que tienen una implementación allí (asumiendo que el padre no es abstracto) también se heredan. Eso significa que la interfaz se hereda y la implementación de este método también. Puedo sobrescribirlo, pero no tengo que hacerlo. Si no lo sobrescribo, he heredado la implementación.
Sin embargo, mi clase también puede "heredar" (no en términos de Java) solo una interfaz, sin implementación. En realidad, las interfaces realmente se llaman así en Java, proporcionan herencia de interfaz, pero sin heredar ninguna implementación, ya que todos los métodos de una interfaz no tienen implementación.
Ahora habia estoArtículo, diciendo que es mejor heredar interfaces que implementaciones.Puede que te guste leerlo (al menos la primera mitad de la primera página), es bastante interesante. Evita problemas como elproblema de clase base frágil. Hasta ahora esto tiene mucho sentido y muchas otras cosas que se dicen en el artículo tienen mucho sentido para mí.
Lo que me molesta de esto es que la herencia de implementación significareutilización de código, una de las propiedades más importantes de los lenguajes OO. Ahora bien, si Java no tuviera clases (como James Gosling, el padrino de Java ha deseado de acuerdo con este artículo), resuelve todos los problemas de la herencia de implementación, pero ¿cómo haría posible la reutilización del código?
P.ej. Si tengo una clase, Car and Car tiene un método move (), que hace que el Car Move se mueva. Ahora puedo subclasificar Car para diferentes tipos de autos, que son todos autos, pero son versiones especializadas de Car. Algunos pueden moverse de una manera diferente, deben sobrescribir move () de todos modos, pero la mayoría simplemente mantendría el movimiento heredado, ya que se mueven de la misma manera que el Coche principal abstracto. Ahora suponga por un segundo que solo hay interfaces en Java, solo que las interfaces pueden heredarse unas de otras, una clase puede implementar interfaces, pero todas las clases son siempre finales, por lo que ninguna clase puede heredar de ninguna otra clase.
¿Cómo evitaría que, cuando tenga un Interfaz y cien clases de Automóviles, necesite implementar un método idéntico move () para cada una de ellas? ¿Qué conceptos para la reutilización de código distintos a la herencia de implementación existen en el mundo OO?
Algunos idiomas tienen mixins. ¿Es Mixins la respuesta a mi pregunta? Leí sobre ellos, pero realmente no puedo imaginar cómo funcionaría Mixins en un mundo Java y si realmente pueden resolver el problema aquí.
Otra idea fue que hay una clase que solo implementa la interfaz Car, llamémosla AbstractCar e implementa el método move (). Ahora, otros autos también implementan la interfaz Car, internamente crean una instancia de AbstractCar e implementan su propio método move () llamando a move () en su Car abstract interno. Pero, ¿no sería esto malgastar recursos para nada (un método que llama simplemente otro método? Está bien, JIT podría incluir el código en línea, pero aún así) y usar memoria adicional para conservar objetos internos, ¿ni siquiera necesitaría la herencia de implementación? (después de todo, cada objeto necesita más memoria que solo la suma de los datos encapsulados). Tampoco es incómodo para un programador escribir métodos ficticios como
public void move() {
abstractCarObject.move();
}
?
¿Alguien puede imaginar una mejor idea de cómo evitar la herencia de implementación y aún así poder reutilizar el código de manera fácil?