¿Existe una razón de uso diferente para las clases / interfaces abstractas en C ++ y Java?

13

Según Herb Sutter, se deberían preferir las interfaces abstractas (todas las funciones virtuales puras) a las clases abstractas en C ++ para desacoplar la implementación en la medida de lo posible. Si bien personalmente me parece muy útil esta regla, recientemente me he unido a un equipo con muchos programadores de Java y, en el código de Java, esta directriz no parece existir. Las funciones y sus implementaciones se ubican muy frecuentemente en clases abstractas. Entonces, me equivoqué con Herb Sutter incluso con 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é?

    
pregunta Martin 07.08.2012 - 22:48

4 respuestas

5

OOP tiene composición y sustitución.

C ++ tiene herencia múltiple, especialización de plantillas, incrustación y semántica de valor / movimiento / puntero.

Java tiene herencia e interfaces únicas, semánticas de incrustación y referencia.

La forma común en que la escuela de OOP utiliza estos idiomas es emplear la herencia para la sustitución de objetos y la incrustación para la composición. Pero también necesitas un ancestro común y una forma de runtime-cast (en C ++ se llama dynamic_cast , en Java es solo pedir una interfaz a otra).

Java hace todo esto por su propia jerarquía java.lang.Object rooted. C ++ no tiene una raíz común predefinida, por lo que al menos debería definirla, para obtener la misma "imagen" (pero esto limita algunas posibilidades de C ++ ...).

Después de eso, la posibilidad de tener un polimorfismo en tiempo de compilación (piense en CRTP) y un valor semántico puede ofrecer también otras alternativas a la manera en que el concepto de "objeto OOP" se puede portar en un programa C ++.

Incluso puede imaginar la herejía de usar la integración y la conversión implícita para administrar la sustitución y la herencia privada para administrar la composición, de hecho, invirtiendo el paradigma de la escuela tradicional. (Por supuesto, 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 (sin implementación) hasta las clases finales (completamente implementada) pasando por interfaces parcialmente implementadas hasta agrupaciones de interfaces uniformes, usando "dominancia" como despacho de interfaz a implementaciones a través de un esquema de herencia "paralelogramo múltiple".

Comparando OOP a java a C ++ suponiendo que solo hay una y solo OOP es limitando las capacidades de ambos idiomas.

Forzar que C ++ se adhiera estrictamente a los lenguajes de codificación de Java es desnaturalizar a C ++ como forzar a Java a comportarse como un lenguaje similar a C ++ que está desnaturalizando a Java.

No es una cuestión de "sensibilidad", sino de diferentes "mecanismos de agregación" que tienen los dos idiomas y una forma diferente de combinarlos que hacen que un idioma sea más rentable en un idioma que en el otro y viceversa.

    
respondido por el Emilio Garavaglia 08.08.2012 - 21:59
12

El principio se aplica a ambos idiomas, pero no está haciendo una comparación justa. Debe comparar las clases abstractas puras de C ++ con las interfaces de Java.

Incluso en C ++, puede tener clases abstractas que tienen algunas de las funciones implementadas, pero derivan de una clase abstracta pura (sin implementaciones). En Java, tendrías las mismas clases abstractas (con algunas implementaciones), que pueden derivar de interfaces (sin implementaciones).

    
respondido por el Luchian Grigore 07.08.2012 - 22:52
4

En general, los mismos principios de 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 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 las clases abstractas y las interfaces. Las clases abstractas se usan para compartir y heredar el comportamiento, mientras que las interfaces se usan simplemente 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 ++") se se utilizan para compartir y heredar el comportamiento, a diferencia del propósito de una interfaz Java (aunque aún se requiere que implemente las funciones), por lo tanto, El uso es diferente de las interfaces de Java.

    
respondido por el Jesse Good 07.08.2012 - 23:50
0

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.

virtual PrintError(string msg) { cout << msg; }

Todavía se puede anular si es realmente necesario, pero puede ahorrarle al cliente algunos problemas al permitirles simplemente llamar a la versión genérica.

    
respondido por el Science_Fiction 07.08.2012 - 23:20

Lea otras preguntas en las etiquetas