Según Herb Sutter, uno debería preferir interfaces abstractas (todas las funciones virtuales puras) a clases abstractas en C ++ para desacoplar la implementación lo más posible. Si bien personalmente considero que esta regla es muy útil, recientemente me uní a un equipo con muchos programadores de Java y, en el código de Java, esta guía no parece existir. Las funciones y sus implementaciones se encuentran muy frecuentemente en clases abstractas. Entonces, ¿entendí mal a Herb Sutter incluso para C ++ o hay una diferencia general en el uso de funciones abstractas en C ++ en comparación con Java. ¿Las clases abstractas con código de implementación son más sensibles en Java que en C ++ y, en caso afirmativo, por qué?
java
c++
interfaces
abstract-class
Martín
fuente
fuente
Respuestas:
OOP tiene composición y sustitución.
C ++ tiene herencia múltiple, especialización de plantilla, incrustación y semántica de valor / movimiento / puntero.
Java tiene herencia única e interfaces, incrustación y semántica de referencia.
La manera común en que la escuela OOP usa estos idiomas es emplear la herencia para la sustitución de objetos y la inclusión para la composición. Pero también necesita un ancestro común y una forma de ejecutar en tiempo de ejecución (en C ++ se llama
dynamic_cast
, en Java solo se le pide una interfaz a otra).Java hace todo esto por su propia
java.lang.Object
jerarquía enraizada. C ++ no tiene una raíz común predefinida, por lo que al menos debería definirla para llegar a una misma "imagen" (pero esto limita algunas posibilidades de C ++ ...).Después de eso, la posibilidad de tener polimorfismo en tiempo de compilación (piense en CRTP) y valor semántico puede ofrecer también otras alternativas a la forma en que el concepto de "objeto OOP" se puede portar a un programa C ++.
Incluso puede imaginar la herejía de utilizar la conversión implícita y la incorporación para gestionar la sustitución y la herencia privada para gestionar la composición, de hecho invirtiendo el paradigma tradicional de la escuela. (Por supuesto, de esta manera es 20 años más joven que la otra, así que no esperes un amplio apoyo de la comunidad para hacerlo)
O puede imaginar una base común virtual para todas las clases, desde la interfaz de formulario (sin implementación) hasta las clases finales (completamente implementadas) pasando por interfaces parcialmente implementadas y grupos de interfaces uniformes, utilizando el "dominio" como envío de la interfaz a las implementaciones a través de un "multi apilado -parallelogram "esquema de herencia.
Comparar OOP con java y C ++ suponiendo que solo haya una y única forma de OOP es limitar las capacidades de ambos lenguajes.
Obligar a C ++ a adherirse estrictamente a los modismos de codificación de Java es desnaturalizar C ++ como forzar a Java a comportarse como un lenguaje similar a C ++ es desnaturalizar Java.
No es una cuestión de "sensibilidad" sino de diferentes "mecanismos de agregación" que los dos idiomas tienen y una forma diferente de combinarlos que hace que un idioma sea más rentable en un idioma que en el otro y viceversa.
fuente
El principio es válido para ambos idiomas, pero no está haciendo una comparación justa. Debe comparar las clases abstractas puras de C ++ con las interfaces Java.
Incluso en C ++, puede tener clases abstractas que tengan implementadas algunas de las funciones, pero que se deriven de una clase abstracta pura (sin implementaciones). En Java, tendría las mismas clases abstractas (con algunas implementaciones), que pueden derivarse de las interfaces (sin implementaciones).
fuente
En general, los mismos principios OO son válidos para Java y C ++. Sin embargo, una gran diferencia es que C ++ admite herencia múltiple, mientras que en Java solo se puede heredar de una clase. Esta es la razón principal por la que Java tiene interfaces, creo, para complementar la falta de herencia múltiple y probablemente para restringir lo que puede hacer con ella (ya que hay muchas críticas sobre el abuso de la herencia múltiple). Entonces, probablemente en la mente de los programadores de Java, hay una distinción más fuerte entre clases abstractas e interfaces. Las clases abstractas se usan para compartir y heredar el comportamiento, mientras que las interfaces simplemente se usan para agregar funcionalidad adicional. Recuerde, en Java puede heredar de una sola clase, pero puede tener muchas interfaces. Sin embargo, en C ++, las clases abstractas puras (es decir, una "interfaz C ++") son se usa para compartir y heredar comportamientos a diferencia del propósito de una interfaz Java (aunque todavía se requiere que implemente las funciones), por lo tanto, el uso es diferente de las interfaces Java.
fuente
A veces tiene sentido tener alguna implementación predeterminada. Por ejemplo, un método genérico PrintError (string msg) que es aplicable a todas las subclases.
Todavía puede anularse si es realmente necesario, pero puede ahorrarle problemas al cliente permitiéndole simplemente llamar a la versión genérica.
fuente