10

Esta no es otra pregunta acerca de la diferencia entre las clases abstractas y las interfaces, así que piense dos veces antes de votar para cerrarla.¿Las interfaces son redundantes con herencia múltiple?

Soy consciente de que las interfaces son esenciales en los lenguajes de OOP que no admiten herencia múltiple, como C# y Java. Pero ¿qué pasa con los con herencia múltiple? ¿Sería un concepto de interfaz (como característica específica del lenguaje) redundante en un lenguaje con herencia múltiple? Supongo que el "contrato" OOP entre clases se puede establecer usando clases abstractas.

O, para decirlo un poco más explícitamente, ¿las interfaces en C# y Java solo son una consecuencia del hecho de que no son compatibles con la herencia múltiple?

+0

No estoy seguro de lo que está pescando aquí: como dice Bozho, las interfaces son una cobertura de nivel de idioma contra alguien que cambia el comportamiento de una clase de forma inesperada al proporcionar una implementación de métodos que solían ser abstractos. –

+0

Los lenguajes MI realmente necesitan esa cobertura o no (ver los comentarios de Ken más abajo, por ejemplo). También esperaba obtener otra opinión fuera de los campamentos Java/C# –

Respuesta

7

... La falta de herencia múltiple nos obligó a añadir el concepto de interfaces de ...

Entonces sí, creo que las interfaces son redundantes dada la herencia múltiple. Puede usar clases básicas abstractas puras en un lenguaje que admite herencia múltiple o mix-ins.

Dicho esto, estoy bastante contento con la herencia individual la mayor parte del tiempo. Eric Lippert señala antes en el mismo volumen (página 10) que la elección de la herencia individual "... elimina de un plumazo muchos de los casos complicados de esquina ..."

8

No, en absoluto. Las interfaces definen contratos sin especificar implementaciones.

Por lo tanto, se necesitan incluso si hay herencia múltiple presente; la herencia se trata de la implementación.

Técnicamente, puede utilizar una clase abstracta en herencia múltiple para simular una interfaz. Pero así uno puede inclinarse a escribir alguna implementación allí, lo que creará grandes problemas.

+1

No lo entiendo. Si está documentado que es y debería ser seguir siendo una interfaz, ¿por qué uno estaría inclinado a agregar una implementación? Si la afirmación es que es posible hacer algo semánticamente correcto hoy, y luego alguien podría modificarlo de una manera que hace un gran desastre, ¿no es cierto de cada característica de idioma? – Ken

+0

¿Significa que, por ejemplo, C++ sufre de no tener interfaces? –

+2

sobre C++ - es subjetivo. No tengo experiencia con él para decir si sufre. @ Ken: cuanto más difícil es mal usar algo, mejor. – Bozho

1

interfaces son preferibles a la herencia múltiple ya la herencia viola la encapsulación de acuerdo con "Effective Java", ítem 16, Favor composition over inheritance.

+0

Entonces, ¿por qué no suprimir la herencia individual? El argumento no tiene sentido. – curiousguy

8

Depende de la prueba para la redundancia.

Si la prueba es "se puede lograr esta tarea sin la función de idioma", entonces las clases en sí mismas son redundantes porque hay lenguajes de competencia de Turing sin clases. O, desde una base de ingeniería, cualquier cosa más allá del código de máquina es redundante.

Realistamente, la prueba es una combinación más sutil de sintaxis y semántica. Una cosa es redundante si no mejora la sintaxis o la semántica de un idioma, para un número razonable de usos.

En los idiomas que hacen la distinción, el soporte de una interfaz declara que una clase sabe cómo conversar de cierta manera. Heredar de otra clase importa (y, probablemente, amplía o modifica) la funcionalidad de otra clase.

Dado que las dos tareas no son lógicamente equivalentes, yo mantengo que las interfaces no son redundantes. Distinguir entre los dos mejora la semántica para una gran cantidad de programas porque puede indicar más específicamente la intención del programador.

+0

Las dos tareas no son equivalentes, pero están indudablemente relacionadas. Heredar una clase implica saber cómo conversar, ¿no es así? –

+0

Sí - el más grande incluye el menor. Pero creo que la capacidad de distinguir entre el lugar donde un autor espera que tenga un diálogo y el lugar donde el autor espera que sea una funcionalidad talentosa es una gran ventaja en un sistema complicado para que las interfaces no sean redundantes. – Tommy

2

Bueno, si va por este camino, podría decir que C y C++, C# y oll otros lenguajes de alto nivel son redundantes porque puede codificar cualquier cosa que desee mediante el ensamblaje. Claro que no necesita absolutamente estos idiomas de alto nivel, sin embargo, ayudan ... mucho.

Todos estos idiomas vienen con varias utilidades. Para algunos de ellos, el concepto de interfaz es una de estas utilidades. Así que sí, en C++, puede evitar el uso de interfaces y el uso de clases abstractas sin implementación.

De hecho, si desea programar Microsoft COM con C, aunque C no conozca el concepto de interfaz, puede hacerlo porque todo.h archivos definen interfaces de esta manera:

#if defined(__cplusplus) && !defined(CINTERFACE) 
    MIDL_INTERFACE("ABCDE000-0000-0000-0000-000000000000") 
    IMyInterface : public IUnknown 
    { 
    ... 
    } 
#else /* C style interface */ 
    typedef struct IMyInterfaceVtbl 
    { 
     BEGIN_INTERFACE 

     HRESULT (STDMETHODCALLTYPE *SomMethod)(... ...); 

     END_INTERFACE 
    } IMyInterfaceVtbl; 

    interface IMyInterface 
    { 
     CONST_VTBL struct IMyInterfaceVtbl *lpVtbl; 
    }; 
#endif 

Una especie de otro azúcar sintáctica ...

Y es cierto que en C#, si no lo hubiera hecho el concepto de interfaz, no sé cómo podría realmente codificar :). En C#, absolutamente necesitamos interfaces.

+0

Pero C# no tiene MI, ¿verdad? Tenga en cuenta que no estoy cuestionando el beneficio de las interfaces. –

+0

absolutamente, C# no tiene MI. El .NET CLR entero no lo tiene, pero algunos lenguajes lo "emulan", como Eiffel: http://msdn.microsoft.com/en-us/library/ms973898.aspx –

4

son interfaces en C# y Java sólo una consecuencia del hecho de que no no son compatibles con la herencia múltiple?

Sí, lo son. Al menos en Java. Como un lenguaje simple, los creadores de Java querían un lenguaje que la mayoría de los desarrolladores pudieran comprender sin una capacitación extensa. Para ello, trabajaron para que el lenguaje fuera lo más similar posible a C++ (familiar) sin sobrecargar la complejidad innecesaria de C++ (simple). Los diseñadores de Java eligieron permitir la herencia de múltiples interfaces mediante el uso de interfaces, una idea tomada de los protocolos de Objective C. See there for details

Y, sí, creo que al igual que en C++, las interfaces son redundantes, si tiene herencia múltiple. Si tiene una característica más poderosa, ¿por qué mantener menos?

5

Hay idiomas que admiten herencia múltiple que no incluyen un concepto paralelo a la interfaz de Java. Eiffel es uno de ellos. Bertrand Meyer no vio la necesidad de ellos, ya que había la posibilidad de definir una clase diferida (que es algo que la mayoría de la gente llama una clase abstracta) con un contrato de desarrollo.

La falta de herencia múltiple puede conducir a situaciones en las que un programador necesita crear una clase de utilidad o similar para evitar escribir código duplicado en objetos que implementan la misma interfaz.

Puede ser que la presencia del contrato haya sido una contribución significativa a la ausencia de un concepto completamente libre de implementación de una interfaz .... Los contratos son más difíciles de escribir sin algunos detalles de implementación para contrastar.

Por lo tanto, técnicamente las interfaces son redundantes en un lenguaje que admite MI.

Pero, como otros han señalado ... la herencia múltiple puede ser una cosa muy difícil de usar correctamente, todo el tiempo. Sé que no pude ... y trabajé para Meyer mientras redactaba Objective Oriented Software Construction, 2da edición.

+1

_ "Hay idiomas que admiten herencia múltiple que no incluyen un concepto paralelo a la interfaz de Java. "_ ¿Conoce algún ejemplo de lo contrario, es decir, el lenguaje MI que tiene un concepto de interfaz separado? –