Conozco la sintaxis, las reglas aplicadas a la clase abstracta y quiero saber el uso de una clase abstracta.
La clase abstracta no puede ser instanciada directamente pero puede ser extendida por otra clase
¿Cuál es la ventaja de hacerlo?
¿Cómo es diferente de una interfaz?
Sé que una clase puede implementar múltiples interfaces pero solo puede extender una clase abstracta. ¿Es esa la única diferencia entre una interfaz y una clase abstracta?
Soy consciente del uso de una interfaz. Lo aprendí del modelo de delegación de eventos de AWT en Java.
¿En qué situaciones debo declarar la clase como una clase abstracta? ¿Cuáles son los beneficios de eso?
java
object-oriented
abstract-class
Vaibhav Jani
fuente
fuente
Respuestas:
Esta respuesta hace un buen trabajo al explicar las diferencias entre una clase abstracta y una interfaz, pero no responde por qué debería declarar una.
Desde un punto de vista puramente técnico, nunca existe el requisito de declarar una clase como abstracta.
Considere las siguientes tres clases:
Usted no tiene que hacer la clase de base de datos abstracto, a pesar de que existe un problema evidente con su aplicación: Al escribir este programa, puede escribir
new Database()
y sería válido, pero que nunca funcionaría.De todos modos, aún obtendría polimorfismo, por lo que mientras su programa solo tenga instancias
SqlDatabase
yOracleDatabase
ejemplos, podría escribir métodos como:Las clases abstractas mejoran la situación al evitar que un desarrollador cree instancias de la clase base, porque un desarrollador la ha marcado como faltante de funcionalidad . También proporciona seguridad en tiempo de compilación para que pueda asegurarse de que cualquier clase que amplíe su clase abstracta brinde la funcionalidad mínima básica para trabajar, y no tenga que preocuparse por poner métodos de código auxiliar (como el anterior) que los herederos de alguna manera tienen para saber mágicamente que tienen que anular un método para que funcione.
Las interfaces son un tema totalmente separado. Una interfaz le permite describir qué operaciones se pueden realizar en un objeto. Normalmente usaría interfaces al escribir métodos, componentes, etc. que usan los servicios de otros componentes, objetos, pero no le importa cuál es el tipo real de objeto del que obtiene los servicios.
Considere el siguiente método:
No le importa si el
database
objeto hereda de un objeto en particular, solo le importa que tenga unaddProduct
método. Entonces, en este caso, una interfaz es más adecuada que hacer que todas sus clases hereden de la misma clase base.A veces la combinación de los dos funciona muy bien. Por ejemplo:
Observe cómo algunas de las bases de datos heredan de RemoteDatabase para compartir alguna funcionalidad (como conectarse antes de escribir una fila), pero FileDatabase es una clase separada que solo se implementa
IProductDatabase
.fuente
Similitudes
Se requieren clases e interfaces abstractas para la abstracción. No se pueden crear instancias con una nueva , pero se pueden resolver mediante la inversión de contenedores de control o mediante patrones de fábrica.
Diferencia
Interfaces
Clase abstracta
En realidad, es fácil encontrar la respuesta mediante una simple consulta de Google .
fuente
En una clase abstracta, puede implementar algunos métodos y dejar (forzar) que el resto sea implementado por la clase extendida. No puede implementar métodos en una interfaz. No puede obligar a nadie a anular nada al extender una clase ordinaria. Con una clase abstracta, puedes.
fuente
Las clases abstractas son para relaciones "es un" y las interfaces son para "puede hacer".
Las clases abstractas le permiten agregar un comportamiento base para que los programadores no tengan que codificar todo, mientras los obligan a seguir su diseño.
fuente
Además de los detalles técnicos profundos, como la implementación de algunos métodos para clases abstractas, etc., el significado es así:
Las interfaces definen la capacidad común: IEnumerable define que la clase que implementa esta interfaz se puede enumerar. No dice nada sobre la clase en sí.
Las clases abstractas (o básicas) definen el comportamiento: WebRequest define un comportamiento común de todas las clases secundarias como HttpWebRequest, etc. Define el significado central de la clase y su propósito real: acceder a los recursos web.
fuente
Entrada de Wikipedia .
Las principales diferencias entre una interfaz y una clase abstracta es que una clase abstracta puede proporcionar métodos implementados. Con las interfaces solo puede declarar métodos, escriba su firma. Aquí hay un ejemplo de una clase que extiende una clase abstracta que implementa dos interfaces: (java)
En este ejemplo, MyAbstractClass proporciona un método público que imprime los tres valores. En ImpClass , debe implementar getValue1 y getValue2 respectivamente desde MyInterface1 y MyInterface2 y getValue3 desde la clase abstracta.
Voilà.
Hay más aspectos (interfaz: solo métodos públicos, clase abstracta: resumen protegido y métodos abstractos públicos) pero puede leerlo usted mismo.
En una nota final, una clase abstracta que solo proporciona métodos abstractos es una clase base abstracta "pura", también conocida como una interfaz.
fuente
En otras palabras, debe comenzar con una pregunta: "¿estas clases necesariamente comparten la implementación , o simplemente tienen una interfaz común ?"
Si la respuesta es mixta, por ejemplo, estas tres clases deben compartir la implementación, pero estas otras dos solo comparten su API, entonces puede hacer una interfaz para los cinco y una clase abstracta para los tres con el común código.
También hay otras formas de compartir la implementación, por ejemplo, para encapsular un objeto con esa implementación (por ejemplo, en el patrón de Estrategia ).
fuente
Declararía un resumen de clase cuando no desee que el desarrollador (probablemente usted mismo) pueda instanciarlo, porque no funcionaría o no tendría sentido.
Por ejemplo, considere un juego donde hay diferentes tipos de entidades de juego. Todos ellos heredan de la
GameEntity
clase base .Esta clase se declara
abstract
ya que no tendría sentido instanciarla. Declara algunas acciones para las entidades del juego y algunos atributos, pero en ninguna parte de esta clase se inicializan estos atributos. Esta clase sirve como plantilla para las entidades del juego, pero no está destinada a ser instanciada por sí misma, y como tal declaradaabstract
.En cuanto a la diferencia de uso entre una clase abstracta y una interfaz:
A mi entender, una interfaz es una forma de obtener un comportamiento polimórfico sin estar limitada por el mecanismo de herencia única de algunos idiomas.
Volvamos al juego como ejemplo. Considere una clase
Enemy
que se deriva deGameEntity
. Esta clase tiene un métodoattackMeFromDistance(RangedAttacker attacker)
. Este método está destinado a permitir que las entidades ataquen al enemigo desde lejos.Como puede ver, este método toma un
RangedAttacker
tipo como parámetro. Sin embargo, todas las entidades del juego ya heredan deGameEntity
. No pueden extender otra clase.Toma las clases
Mage
yArcher
por ejemplo. Queremos permitir que ambos sean aceptados como parámetros en elattackMeFromDistance(RangedAttacker attacker)
método, pero ya se derivan de ellosGameEntity
.Para resolver esto, creamos una nueva interfaz:
Una clase que implementa esta interfaz debe implementar el
attackFromDistance()
método y, por lo tanto, se garantiza que tiene capacidades de ataque a distancia. Esto significa que elattackMeFromDistance
método ahora puede aceptar con seguridad las clases que implementan esta interfaz. Entonces, hacerMage
eArcher
implementar esa interfaz resuelve nuestro problema.Para mí, este es el poder de las interfaces.
Para resumir, generalmente usaría una clase abstracta cuando desee tener una clase base para algunas clases, pero no tendría sentido instanciarla por sí misma (o en el caso de que tenga
abstract
métodos, eso tiene que ser implementado por las subclases, y en este caso el compilador lo obligaría a hacer la claseabstract
). Usaría una interfaz para obtener un comportamiento polimórfico sin estar limitado por el mecanismo de herencia única.fuente
fuente