¿Hay alguna diferencia entre las interfaces y las clases abstractas que solo tienen métodos abstractos?

9

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.

yfklon
fuente
¿cual idioma?
Kevin Cline
Por lo que puedo decir, su pregunta se responde por duplicado dos veces : aquí y aquí . Y estas dos respuestas son independientes del lenguaje, nada específico para C # allí
mosquito
3
@blank No estoy de acuerdo con el estado Duplicado aplicado a su pregunta, así que lo volví a abrir. Además, edité su pregunta para aclarar más lo que creo que está preguntando.
maple_shaft

Respuestas:

22

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.

pdr
fuente
44
+1, aunque los gatos arrojan de una manera mucho más molesta que las serpientes o las lagartijas.
Matthew Flynn
Técnicamente: los métodos abstractos pueden protegerse. Los métodos de interfaz no pueden.
Jacques Koorts
19

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.

herzmeister
fuente
3
¿más? ¿cuáles estás contando? La mayoría de los lenguajes OOP que conozco no tienen interfaces o clases abstractas. C ++ solo tiene clases abstractas.
Kevin Cline
10
@kevincline: probablemente C #, Java y VB.NET.
tdammers
1
@kevincline, creo que solo falta un "tener ambos". IIRC, en Ada, la motivación para la interfaz era esa, los diseñadores no querían una característica general de herencia múltiple, pero el caso especial de la interfaz se consideró demasiado importante para no proporcionarse.
Programador
@tdammers: LOL. Eso fue una broma, ¿verdad?
Kevin Cline
3

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 Cares a Vehicley Doges an Animal. Con una interfaz, lo que hace el objeto es lo que importa. Así que ambos Cary Dogcan Move()y el consumidor lo saben porque lo implementan Movable, pero un automóvil definitivamente no es un Dogo un Animal. 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.

Ivan Pintar
fuente
La interfaz también es un tipo, por lo que podría tener un IAnimal que sonDog y Cat son .
Amy Blankenship
Podría, pero en mi opinión, las interfaces son sobre el comportamiento que está expuesto al mundo exterior, y no tanto sobre lo que son los objetos. La herencia implica que algo es un tipo de otra cosa (el gato es un animal). Una interfaz solo dice lo que ese objeto puede hacer. Es por eso que me gusta decir que algo "implementa" en lugar de "hereda" de una interfaz, que es lo que diría la mayoría de las personas .Net con las que he trabajado (supongo que la sintaxis es la misma para la herencia y la implementación).
Ivan Pintar el
2

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.

Thomas
fuente
1
Los métodos virtuales protegidos (con capacidad de anulación) pueden ser útiles para las clases que forman parte de un marco o algo así. De esa manera se aseguran de que el código personalizado en una clase que hereda el resumen proporcione esa funcionalidad. Aunque esto también se puede lograr heredando una interfaz en la clase base pero no implementando realmente sus métodos
Ivan Pintar
Sí, estaba pensando en algo así, pero no tengo experiencia con eso, así que no podía juzgar. Gracias por el aporte.
Thomas
Solo una nota. En algunos idiomas, los métodos virtuales privados pueden anularse en clases derivadas.
Johan Boulé
2

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.

Kevin Cline
fuente
2

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

tgkprog
fuente
1
¿No se definen los métodos abstractos sin ninguna implementación y dejan la implementación a las clases heredadas?
Ivan Pintar
sí, tienes razón, entonces supongo que son solo las variables, los constructores y los métodos estáticos y privados si los
cuentas
@Pinetree, en la práctica la mayoría de las veces querrás al menos un pequeño código "real" en tus clases abstractas (al menos en el lenguaje que uso, que no tiene una construcción especial para las clases abstractas).
Amy Blankenship
@AmyBlankenship sí, la mayoría de las veces las clases abstractas tienen código "real" (para eso están). Pero me refería a métodos abstractos, dentro del contexto de una clase puramente abstracta que sirve como interfaz en un lenguaje como C ++, que no tiene interfaces.
Ivan Pintar el