Digamos que tenemos una clase abstracta y que esta clase solo tenga métodos abstractos. ¿Es esta clase abstracta diferente de una interfaz que solo tiene los mismos métodos?
Lo que estoy buscando saber es si hay diferencias filosóficas, objetivas y en la implementación del lenguaje de programación subyacente entre una clase abstracta con solo miembros abstractos y una interfaz equivalente.
Respuestas:
Técnicamente, las diferencias no son realmente significativas pero, conceptualmente, son cosas completamente diferentes y eso conduce a las diferencias técnicas que otros han mencionado.
Una superclase abstracta es exactamente lo que parece, es un tipo común que es compartido por muchos otros tipos, como los gatos y los perros son animales.
Una interfaz también es exactamente lo que parece, es una interfaz a través de la cual otras clases pueden comunicarse con el objeto. Si desea hacer una caminata de gato, está bien, porque Cat implementa una interfaz CanWalk. Lo mismo para un lagarto, aunque caminan de manera muy diferente. Una serpiente, por otro lado, no implementa CanWalk, por lo que no puede decirle que camine. Mientras tanto, Lizard y Snake (o posiblemente subclases más explícitas, no soy un experto) podrían deshacerse de su piel y, por lo tanto, implementar CanShed, mientras que un gato no podría hacer eso.
Pero todos siguen siendo animales y tienen algunas propiedades comunes, como si están vivos o muertos.
Es por eso que todos los métodos en una interfaz deben implementarse como públicos (o explícitamente, en C #). ¿Porque cuál es el punto en una interfaz que está oculta de la clase que interactúa con el objeto? También es la razón por la que puede tener múltiples interfaces para un objeto, incluso cuando un idioma no admite herencia múltiple.
Para volver a su pregunta, cuando la mira de esta manera, rara vez hay una razón para tener una superclase completamente abstracta.
fuente
En la mayoría de los lenguajes OOP, una clase de implementación solo puede derivar de una clase abstracta, pero implementa múltiples interfaces.
fuente
En un lenguaje como C ++ que permite la herencia múltiple y no tiene interfaces, las clases abstractas en las que todos los métodos son abstractos pueden servir como interfaces. No he trabajado tanto con C ++, pero supongo que la herencia múltiple puede causar problemas cuando hay métodos con el mismo nombre en las clases base.
En lenguajes como PHP y C #, las interfaces proporcionan un medio para lograr un polimorfismo similar, aunque no me gusta llamarlo "herencia" ya que existe una diferencia conceptual entre heredar una clase abstracta e implementar una interfaz. Las interfaces eliminan el problema del conflicto, ya que ellos mismos no proporcionan implementación.
Una interfaz sirve como un contrato con el mundo exterior, mientras que una clase abstracta puede proporcionar una implementación, aunque si se usa para "falsificar" una interfaz, lo más probable es que no lo haga.
La principal diferencia conceptual es que cuando una clase hereda otra clase (abstracta o no), existe una relación de "es", entonces a
Car
es aVehicle
yDog
es anAnimal
. Con una interfaz, lo que hace el objeto es lo que importa. Así que ambosCar
yDog
canMove()
y el consumidor lo saben porque lo implementanMovable
, pero un automóvil definitivamente no es unDog
o unAnimal
. Y la implementación del movimiento será diferente (ruedas frente a patas) pero al código consumidor no le importa y no debería importarle. Las interfaces tienen que ver con el código consumidor, más que con la implementación.El punto principal es que si tiene interfaces en el idioma de su elección, úselas para las cosas para las que están allí. Si no (como en C ++), puede simularlos usando clases abstractas puras.
fuente
Dog
yCat
son .Las clases abstractas pueden presentar métodos abstractos protegidos (en los idiomas con los que estoy trabajando), en las interfaces los métodos suelen ser siempre públicos. Si esta diferencia permite explotaciones útiles, no lo sé.
Editar Primero pensé que un método abstracto privado no sirve, pero ahora recordé que puede usarse para garantizar que ese método nunca se llame. De esta manera puede evitar que se llame a un constructor de copia de un objeto.
fuente
Si, son diferentes. De lo contrario, los diseñadores de idiomas no habrían proporcionado ambos. Sé de dos lenguajes que separan las clases y las interfaces: Java y C #, clon mutante de Java. Los diseñadores crearon interfaces para evitar la herencia de clases múltiples. La mayoría de los otros idiomas admiten herencia de clases múltiples y, en consecuencia, no separan clases e interfaces.
fuente
Creo que la principal diferencia es que: en una clase abstracta, incluso si todos los métodos son todos abstractos, aún pueden proporcionar miembros de datos (variables de instancia) y algo de código a las clases que lo implementan (en forma de métodos privados o constructores), bloques estáticos; haciendo parte del trabajo para las subclases y ayudándoles con la implementación.
Un efecto secundario positivo: el código está en un lugar, por lo que es un lugar para hacer correcciones. las subclases pueden simplemente llamar al método de superclase y luego hacer algo más o nada si las acciones de superclase son suficientes para su caso. Super class quiere que cada subclase tome esta decisión, por lo que ha marcado toda su implementación como abstracta (algunas también pueden estar vacías)
No es relevante para la pregunta: pero tener interfaces significa que una clase puede implementar dos contratos diferentes. Esa es una ventaja de una interfaz sobre una superclase abstracta
fuente