Interfaz vs clase abstracta (OO general)
Recientemente tuve dos entrevistas telefónicas en las que me preguntaron sobre las diferencias entre una clase de interfaz y una clase abstracta. Les he explicado todos los aspectos que se me han ocurrido, pero parece que están esperando que mencione algo específico y no sé qué es.
Por mi experiencia creo que lo siguiente es cierto. Si me falta un punto importante, hágamelo saber.
Interfaz:
Cada método declarado en una interfaz deberá implementarse en la subclase. Solo pueden existir eventos, delegados, propiedades (C#) y métodos en una interfaz. Una clase puede implementar múltiples interfaces.
Clase abstracta:
La subclase solo debe implementar métodos abstractos. Una clase abstracta puede tener métodos normales con implementaciones. Una clase abstracta también puede tener variables de clase además de Eventos, Delegados, Propiedades y Métodos. Una clase puede implementar una clase abstracta solo debido a la inexistencia de herencia múltiple en C#.
Después de todo eso, al entrevistador se le ocurrió la pregunta "¿Qué pasaría si tuviera una clase abstracta con sólo métodos abstractos? ¿En qué se diferenciaría de una interfaz?" No sabía la respuesta pero creo que es la herencia como se mencionó anteriormente, ¿verdad?
Otro entrevistador me preguntó: "¿Qué pasaría si tuvieras una variable pública dentro de la interfaz? ¿En qué se diferenciaría de una clase abstracta?" Insistí en que no puedes tener una variable pública dentro de una interfaz. No sabía lo que quería oír pero tampoco estaba satisfecho.
Ver también :
Cuándo usar una interfaz en lugar de una clase abstracta y viceversa
Interfaces frente a clases abstractas
¿Cómo se decide entre utilizar una clase abstracta y una interfaz?
¿Cuál es la diferencia entre una interfaz y una clase abstracta?
¿Qué tal una analogía? Cuando estaba en la Fuerza Aérea, fui a un entrenamiento de piloto y me convertí en piloto de la USAF (Fuerza Aérea de EE. UU.). En ese momento no estaba calificado para volar nada y tuve que asistir a un entrenamiento de tipo avión. Una vez que califiqué, fui piloto (clase abstracta) y piloto de C-141 (clase concreta). En una de mis asignaciones, se me asignó una tarea adicional: Oficial de seguridad. Ahora todavía era piloto y piloto de C-141, pero también desempeñaba funciones de Oficial de Seguridad (implementé ISafetyOfficer, por así decirlo). No era necesario que un piloto fuera responsable de seguridad, otras personas también podrían haberlo hecho.
Todos los pilotos de la USAF deben seguir ciertas regulaciones de toda la Fuerza Aérea, y todos los pilotos de C-141 (o F-16 o T-38) "son" pilotos de la USAF. Cualquiera puede ser responsable de seguridad. Entonces, para resumir:
- Piloto: clase abstracta
- Piloto C-141: clase concreta
- Oficial de seguridad: interfaz
Nota agregada: esto pretendía ser una analogía para ayudar a explicar el concepto, no una recomendación de codificación. Vea los diversos comentarios a continuación, la discusión es interesante.
Si bien su pregunta indica que es para "OO general", realmente parece centrarse en el uso de estos términos en .NET.
En .NET (similar para Java):
- Las interfaces no pueden tener estado o implementación.
- una clase que implementa una interfaz debe proporcionar una implementación de todos los métodos de esa interfaz
- las clases abstractas pueden contener estado (miembros de datos) y/o implementación (métodos)
- las clases abstractas se pueden heredar sin implementar los métodos abstractos (aunque dicha clase derivada es abstracta en sí misma)
- las interfaces pueden ser de herencia múltiple, las clases abstractas pueden no (esta es probablemente la razón concreta clave para que las interfaces existan separadas de las clases abstractas: permiten una implementación de herencia múltiple que elimina muchos de los problemas de la MI general).
Como términos generales de OO, las diferencias no están necesariamente bien definidas. Por ejemplo, hay programadores de C++ que pueden tener definiciones rígidas similares (las interfaces son un subconjunto estricto de clases abstractas que no pueden contener implementación), mientras que algunos pueden decir que una clase abstracta con algunas implementaciones predeterminadas sigue siendo una interfaz o que una clase no abstracta La clase todavía puede definir una interfaz.
De hecho, existe un modismo de C++ llamado Interfaz no virtual (NVI) donde los métodos públicos son métodos no virtuales que "conectan" con métodos virtuales privados:
- http://www.gotw.ca/publications/mill18.htm
- http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Non-Virtual_Interface
Creo que la respuesta que buscan es la diferencia filosófica fundamental o OPPS.
La herencia de clases abstractas se utiliza cuando la clase derivada comparte las propiedades principales y el comportamiento de la clase abstracta. El tipo de comportamiento que realmente define la clase.
Por otro lado, la herencia de interfaz se utiliza cuando las clases comparten comportamientos periféricos, que no necesariamente definen la clase derivada.
Por ej. Un automóvil y un camión comparten muchas propiedades y comportamientos centrales de una clase abstracta de automóvil, pero también comparten algunos comportamientos periféricos como generar escape, que incluso clases que no son automóviles, como perforadores o generadores de energía, comparten y no necesariamente definen un automóvil o un camión. , por lo que Car, Truck, Driller y PowerGenerator pueden compartir la misma interfaz IExhaust.
Breve: las clases abstractas se utilizan para modelar una jerarquía de clases de clases de apariencia similar (por ejemplo, Animal puede ser una clase abstracta y Human, Lion, Tiger pueden ser clases derivadas concretas)
Y
La interfaz se utiliza para la comunicación entre 2 clases similares/no similares a las que no les importa el tipo de clase que implementa la interfaz (por ejemplo, la altura puede ser una propiedad de la interfaz y puede ser implementada por Humano, Edificio o Árbol. No importa si puedes comer , puedes nadar, puedes morir o cualquier cosa... solo importa una cosa: necesitas tener altura (implementación en tu clase).