Me hicieron una pregunta, quería que revisaran mi respuesta aquí.
P: ¿ En qué escenario es más apropiado extender una clase abstracta en lugar de implementar la (s) interfaz (s)?
R: Si usamos el patrón de diseño del método de plantilla.
Estoy en lo correcto ?
Lamento no haber podido formular la pregunta con claridad.
Conozco la diferencia básica entre clase abstracta e interfaz.
1) use la clase abstracta cuando el requisito sea tal que necesitemos implementar la misma funcionalidad en cada subclase para una operación específica (implementar el método) y una funcionalidad diferente para algunas otras operaciones (solo firmas de métodos)
2) use la interfaz si necesita poner la firma para que sea la misma (y la implementación diferente) para que pueda cumplir con la implementación de la interfaz
3) podemos extender un máximo de una clase abstracta, pero podemos implementar más de una interfaz
Reiterando la pregunta: ¿Hay otros escenarios, además de los mencionados anteriormente, en los que específicamente requerimos usar la clase abstracta (uno es ver que el patrón de diseño del método de plantilla se basa conceptualmente solo en esto)?
Interfaz frente a clase abstracta
Elegir entre estos dos depende realmente de lo que quieras hacer, pero por suerte para nosotros, Erich Gamma puede ayudarnos un poco.
Como siempre hay una compensación, una interfaz le da libertad con respecto a la clase base, una clase abstracta le da la libertad de agregar nuevos métodos más adelante . - Erich Gamma
No puede ir y cambiar una interfaz sin tener que cambiar muchas otras cosas en su código, por lo que la única forma de evitar esto sería crear una interfaz completamente nueva, lo que podría no siempre ser algo bueno.
Abstract classes
debe usarse principalmente para objetos que están estrechamente relacionados. Interfaces
son mejores para proporcionar funciones comunes para clases no relacionadas.
fuente
Respuestas:
Cuándo utilizar interfaces
Una interfaz le permite a alguien comenzar desde cero para implementar su interfaz o implementar su interfaz en algún otro código cuyo propósito original o principal era bastante diferente de su interfaz. Para ellos, su interfaz es solo incidental, algo que deben agregar a su código para poder usar su paquete. La desventaja es que todos los métodos de la interfaz deben ser públicos. Es posible que no desee exponer todo.
Cuándo usar clases abstractas
Una clase abstracta, por el contrario, proporciona más estructura. Por lo general, define algunas implementaciones predeterminadas y proporciona algunas herramientas útiles para una implementación completa. El problema es que el código que lo usa debe usar su clase como base. Eso puede ser muy inconveniente si los otros programadores que desean usar su paquete ya han desarrollado su propia jerarquía de clases de forma independiente. En Java, una clase puede heredar de una sola clase base.
Cuándo usar ambos
Puede ofrecer lo mejor de ambos mundos, una interfaz y una clase abstracta. Los implementadores pueden ignorar su clase abstracta si así lo desean. El único inconveniente de hacer eso es llamar a métodos a través de su nombre de interfaz es un poco más lento que llamarlos a través de su nombre de clase abstracto.
fuente
If we are using template method design pattern
No podemos decirYES
oNO
Sí, si usa JAXB. No le gustan las interfaces. Debería utilizar clases abstractas o solucionar esta limitación con genéricos.
A partir de un blog personal de post :
Interfaz:
En general, las interfaces deben usarse para definir contratos (qué se debe lograr, no cómo lograrlo).
Clase abstracta:
Las clases abstractas deben usarse para la implementación (parcial). Pueden ser un medio para restringir la forma en que se deben implementar los contratos de API.
fuente
default
ystatic
.La interfaz se usa cuando tiene un escenario en el que todas las clases tienen la misma estructura pero tienen una funcionalidad totalmente diferente.
La clase abstracta se usa cuando tiene un escenario en el que todas las clases tienen la misma estructura pero algunas funciones iguales y otras diferentes.
Eche un vistazo al artículo: http://shoaibmk.blogspot.com/2011/09/abstract-class-is-class-which-cannot-be.html
fuente
Hay muchas respuestas excelentes aquí, pero a menudo encuentro que usar AMBAS interfaces y clases abstractas es la mejor ruta. Considere este ejemplo artificial:
Eres desarrollador de software en un banco de inversión y necesitas crear un sistema que coloque pedidos en un mercado. Su interfaz de captura la idea más general de lo que un sistema de comercio hace ,
1) Trading system places orders 2) Trading system receives acknowledgements
y se puede capturar en una interfaz,
ITradeSystem
public interface ITradeSystem{ public void placeOrder(IOrder order); public void ackOrder(IOrder order); }
Ahora los ingenieros que trabajan en el mostrador de ventas y en otras líneas comerciales pueden comenzar a interactuar con su sistema para agregar la funcionalidad de colocación de pedidos a sus aplicaciones existentes. ¡Y aún no has comenzado a construir! Este es el poder de las interfaces.
Así que continúe y construya el sistema para los comerciantes de acciones ; ¡Han escuchado que su sistema tiene una función para encontrar acciones baratas y están ansiosos por probarlo! Captura este comportamiento en un método llamado
findGoodDeals()
, pero también se da cuenta de que hay muchas cosas complicadas que están involucradas en la conexión a los mercados. Por ejemplo, tienes que abrir unSocketChannel
,public class StockTradeSystem implements ITradeSystem{ @Override public void placeOrder(IOrder order); getMarket().place(order); @Override public void ackOrder(IOrder order); System.out.println("Order received" + order); private void connectToMarket(); SocketChannel sock = Socket.open(); sock.bind(marketAddress); <LOTS MORE MESSY CODE> } public void findGoodDeals(); deals = <apply magic wizardry> System.out.println("The best stocks to buy are: " + deals); }
Las implementaciones concretas van a tener muchos de estos métodos desordenados como
connectToMarket()
, perofindGoodDeals()
es lo único que realmente les importa a los traders.Aquí es donde entran en juego las clases abstractas. Su jefe le informa que los comerciantes de divisas también quieren utilizar su sistema. Y al observar los mercados de divisas, se ve que las tuberías son casi idénticas a las de los mercados de valores. De hecho,
connectToMarket()
se puede reutilizar literalmente para conectarse a los mercados de divisas. Sin embargo,findGoodDeals()
es un concepto muy diferente en el ámbito de las divisas. Entonces, antes de pasar el código base al chico mago de las divisas al otro lado del océano, primero refactoriza en unabstract
clase, dejando sinfindGoodDeals()
implementarpublic abstract class ABCTradeSystem implements ITradeSystem{ public abstract void findGoodDeals(); @Override public void placeOrder(IOrder order); getMarket().place(order); @Override public void ackOrder(IOrder order); System.out.println("Order received" + order); private void connectToMarket(); SocketChannel sock = Socket.open(); sock.bind(marketAddress); <LOTS MORE MESSY CODE> }
Su sistema de negociación de acciones implementa
findGoodDeals()
como ya lo ha definido,public class StockTradeSystem extends ABCTradeSystem{ public void findGoodDeals(); deals = <apply magic wizardry> System.out.println("The best stocks to buy are: " + deals); }
pero ahora el genio FX puede construir su sistema simplemente proporcionando una implementación de
findGoodDeals()
para las divisas; ¡no tiene que volver a implementar las conexiones de socket o incluso los métodos de interfaz!public class CurrencyTradeSystem extends ABCTradeSystem{ public void findGoodDeals(); ccys = <Genius stuff to find undervalued currencies> System.out.println("The best FX spot rates are: " + ccys); }
La programación en una interfaz es poderosa, pero las aplicaciones similares a menudo vuelven a implementar métodos de formas casi idénticas. El uso de una clase abstracta evita nuevas implementaciones, al tiempo que conserva el poder de la interfaz.
Nota: uno puede preguntarse por qué
findGreatDeals()
no forma parte de la interfaz. Recuerde, la interfaz define los componentes más generales de un sistema comercial. Otro ingeniero puede desarrollar un sistema de comercio COMPLETAMENTE DIFERENTE, en el que no les importa encontrar buenas ofertas. La interfaz garantiza que la mesa de ventas también pueda interactuar con su sistema, por lo que es preferible no enredar su interfaz con conceptos de aplicación como "grandes ofertas".fuente
¿Cuáles deberías usar, clases abstractas o interfaces?
Considere usar clases abstractas si alguna de estas declaraciones se aplica a su caso de uso:
Quieres compartir código entre varias clases estrechamente relacionadas.
Espera que las clases que amplían su clase abstracta tengan muchos métodos o campos comunes, o requieran modificadores de acceso distintos de los públicos (como protegidos y privados).
Quiere declarar campos no estáticos o no finales. Esto le permite definir métodos que pueden acceder y modificar el estado del objeto al que pertenecen.
Considere el uso de interfaces si alguna de estas declaraciones se aplica a su caso de uso:
Espera que clases no relacionadas implementen su interfaz. Por ejemplo, las interfaces Comparable y Cloneable son implementadas por muchas clases no relacionadas.
Desea especificar el comportamiento de un tipo de datos en particular, pero no le preocupa quién implementa su comportamiento.
Desea aprovechar la herencia múltiple de tipos.
http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html
fuente
Las cosas han cambiado mucho en los últimos tres años con la adición de nuevas capacidades para interactuar con la versión de Java 8.
Desde la página de documentación de Oracle en la interfaz:
Como citó en su pregunta, la clase abstracta se ajusta mejor al patrón de método de plantilla en el que debe crear un esqueleto. La interfaz no se puede utilizar aquí.
Una consideración más para preferir la clase abstracta sobre la interfaz:
No tiene implementación en la clase base y solo las subclases tienen que definir su propia implementación. Necesita una clase abstracta en lugar de una interfaz, ya que desea compartir el estado con las subclases.
La clase abstracta establece "es una" relación entre clases relacionadas y la interfaz proporciona "tiene una" capacidad entre clases no relacionadas .
Con respecto a la segunda parte de su pregunta, que es válida para la mayoría de los lenguajes de programación, incluido java antes del lanzamiento de java-8
Si prefiere la clase abstracta para interactuar antes con las dos consideraciones anteriores, debe volver a pensar ahora, ya que los métodos predeterminados han agregado capacidades poderosas a las interfaces.
Para seleccionar uno de ellos entre interfaz y clase abstracta, la página de documentación de Oracle cita que:
Consulte estas preguntas relacionadas para obtener más detalles:
Interfaz vs clase abstracta (OO general)
¿Cómo debería haber explicado la diferencia entre una interfaz y una clase abstracta?
En resumen: la balanza se inclina más hacia las interfaces ahora .
Algunos patrones de diseño usan clases abstractas (sobre interfaces) además del patrón del método Template.
Patrones de creación:
Abstract_factory_pattern
Patrones estructurales:
Decorator_pattern
Patrones de comportamiento:
Mediator_pattern
fuente
No tienes razón. Hay muchos escenarios. Simplemente no es posible reducirlo a una sola regla de 8 palabras.
fuente
La respuesta más corta es extender la clase abstracta cuando algunas de las funcionalidades que busca ya estén implementadas en ella.
Si implementa la interfaz, debe implementar todo el método. Pero para la clase abstracta, el número de métodos que necesita implementar podría ser menor.
En el patrón de diseño de la plantilla debe haber un comportamiento definido. Este comportamiento depende de otros métodos que son abstractos. Al crear una subclase y definir esos métodos, realmente define el comportamiento principal. El comportamiento subyacente no puede estar en una interfaz ya que la interfaz no define nada, solo declara. Entonces, un patrón de diseño de plantilla siempre viene con una clase abstracta. Si desea mantener intacto el flujo del comportamiento, debe extender la clase abstracta pero no anular el comportamiento principal.
fuente
Pure virtual functions can also be used where the method declarations are being used to define an interface - similar to what the interface keyword in Java explicitly specifies. In such a use, derived classes will supply all implementations. In such a design pattern, the abstract class which serves as an interface will contain only pure virtual functions, but no data members or ordinary methods.
parte (1/2)no data members or ordinary methods
[en la clase abstracta].En mi opinión, la diferencia básica es que
an interface can't contain non abstract methods while an abstract class can
. Entonces, si las subclases comparten un comportamiento común, este comportamiento puede implementarse en la superclase y, por lo tanto, heredarse en las subclases.También cité lo siguiente del libro "Ppatterns de diseño de arquitectura de software en Java"
"En el lenguaje de programación Java no hay soporte para la herencia múltiple. Eso significa que una clase puede heredar solo de una sola clase. Por lo tanto, la herencia debe usarse solo cuando sea absolutamente necesario. Siempre que sea posible, los métodos que denotan el comportamiento común deben declararse en la forma de una interfaz Java para ser implementada por diferentes clases de implementadores. Pero las interfaces tienen la limitación de que no pueden proporcionar implementaciones de métodos. Esto significa que cada implementador de una interfaz debe implementar explícitamente todos los métodos declarados en una interfaz, incluso cuando algunos de estos Los métodos representan la parte invariable de la funcionalidad y tienen exactamente la misma implementación en todas las clases del implementador, lo que conduce a un código redundante.El siguiente ejemplo demuestra cómo el patrón Abstract Parent Class puede usarse en tales casos sin requerir implementaciones de métodos redundantes.
fuente
Las clases abstractas son diferentes de las interfaces en dos aspectos importantes
fuente
Esta es una buena pregunta. Los dos no son similares, pero pueden usarse por alguna de las mismas razones, como una reescritura. Al crearlo, es mejor utilizar Interface. Cuando se trata de clase, es bueno para depurar.
fuente
Abstract classes should be extended when you want to some common behavior to get extended
. La superclase Abstract tendrá el comportamiento común y definirá el método abstracto / comportamiento específico que las subclases deben implementar.Interfaces allows you to change the implementation anytime allowing the interface to be intact
.fuente
Este es mi entendimiento, espero que esto ayude
Clases abstractas:
Interfaces:
fuente
Uso de resumen e interfaz:
Uno tiene "Es-una-relación" y otro tiene "Tiene-una-relación"
Las propiedades predeterminadas se han establecido en abstracto y las propiedades adicionales se pueden expresar a través de la interfaz.
Ejemplo: -> En los seres humanos tenemos algunas propiedades predeterminadas que son comer, dormir, etc. pero si alguien tiene otras actividades curriculares como nadar, jugar, etc., las podría expresar Interface.
fuente