Si bien ciertas pautas establecen que debe usar una interfaz cuando quiere definir un contrato para una clase donde la herencia no es clara (IDomesticated
) y la herencia cuando la clase es una extensión de otra (Cat : Mammal
, Snake : Reptile
), hay casos en los que (en mi opinión) estas pautas entran en un área gris.Cuándo usar interfaces o clases abstractas? Cuándo usar ambos?
Por ejemplo, supongamos que mi implementación fue Cat : Pet
. Pet
es una clase abstracta. En caso de que se ampliara a Cat : Mammal, IDomesticated
donde Mammal
es una clase abstracta y IDomesticated
es una interfaz? ¿O estoy en conflicto con los principios KISS/YAGNI (aunque no estoy seguro de si habrá una clase Wolf
en el futuro, que no podría heredar de Pet
)?
Alejándonos del metafórico Cat
sy Pet
s, digamos que tengo algunas clases que representan fuentes de datos entrantes. Todos necesitan implementar la misma base de alguna manera. Podría poner en práctica algo de código genérico de una clase abstracta Source
y heredar de ella. También podría simplemente hacer una interfaz ISource
(que se siente más "derecho" a mí) y volver a implementar el código genérico en cada clase (que es menos intuitivo). Finalmente, pude "tener el pastel y comérselo" haciendo tanto la clase abstracta como la interfaz. ¿Qué es mejor?
Estos dos casos muestran los puntos para utilizar solo una clase abstracta, solo una interfaz y el uso de una clase abstracta y una interfaz. ¿Son todas estas elecciones válidas, o hay "reglas" para cuando una debería usarse sobre otra?
me gustaría aclarar que por "utilizando tanto una clase abstracta y una interfaz" que incluye el caso cuando representan esencialmente la misma cosa (Source
y ISource
ambos tienen los mismos miembros), pero la clase agrega funcionalidad genérica mientras que la interfaz especifica el contrato.
También vale la pena señalar que esta pregunta es principalmente para los idiomas que no admiten herencia múltiple (como .NET y Java).
Me gustaría notar que vi varias preguntas de "Interfaz vs. Clases abstractas", pero en esta pregunta, estoy más que interesado en saber cuándo usar las interfaces * both * y las clases abstractas (si esto es una cosa válida que hacer.) – Blixt
posible duplicado de [Interface vs Abstract Class (OO general)] (http://stackoverflow.com/questions/761194/interface-vs-abstract-class-general-oo) –
posible duplicado de [¿Cuándo utilizar una interfaz en lugar de una clase abstracta y viceversa?] (Http://stackoverflow.com/questions/479142/when-to-use-an-interface-instead-of-an-abstract-class-and -vice-versa) – nawfal