¿Pueden las clases abstractas reemplazar las interfaces? [duplicar]


Esta pregunta ya tiene una respuesta aquí:

En Java, puede crear una clase abstracta que contenga solo métodos abstractos. Por otro lado, puede crear una interfaz que declare los mismos métodos. Siendo ese el caso, puedes usar clases abstractas en su lugar de interfaces?

Author: Makoto, 2010-01-24

12 answers

No siempre:

  • una clase puede extender solo una clase
  • una clase puede implementar más de una interfaz

Sun docs haga una comparación más detallada:

Clases abstractas versus Interfaces

A diferencia de las interfaces, las clases abstractas pueden contener campos que no son estáticos y finales, y pueden contener métodos implementados. Tales clases abstractas son similares a las interfaces, excepto que proporcionan una implementación parcial, dejando que las subclases completen la implementación. Si una clase abstracta contiene solo declaraciones de métodos abstractos, debe declararse como una interfaz en su lugar.

Las clases pueden implementar múltiples interfaces en cualquier lugar de la jerarquía de clases, estén o no relacionadas entre sí de alguna manera. Piense en Comparable o Cloneable, por ejemplo.

En comparación, las clases abstractas son más comúnmente subclases para compartir piezas de aplicación. Una sola clase abstracta es subclasificada por clases similares que tienen mucho en común (las partes implementadas de la clase abstracta), pero también tienen algunas diferencias (los métodos abstractos).

 34
Author: Bozho,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-23 23:08:30

En algunos casos se puede utilizar una clase abstracta en lugar de interfaz. Sin embargo, casi nunca es una buena idea hacerlo. En general, debe usar la regla:

  1. Las interfaces especifican el comportamiento.
  2. Las clases abstractas especifican la implementación.

El otro "problema" con el uso de clases abstractas es que ya no puede implementar mixins, es decir, puede implementar múltiples interfaces, sin embargo, solo puede extender una clase abstracta.

 12
Author: Paul Wagland,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-03 11:25:21

Un punto que falta en las respuestas aquí es la idea de quién implementará la interfaz.

Si su componente quiere devolver instancias de tipos abstractos a sus llamantes, donde los tipos concretos están definidos internamente y ocultos a los llamantes, use una interfaz . Por el contrario, si su componente consume o acepta instancias de tipos abstractos que sus llamadores deben implementar, las clases abstractas son por lo general una mejor opción.

Anticipar la evolución y mantener la compatibilidad binaria inclina la balanza aquí. Con una clase abstracta, puede agregar métodos y, si proporciona una implementación base, las implementaciones existentes de la clase abstracta continuarán funcionando bien. Con una interfaz, agregar un método rompe la compatibilidad binaria, ya que ninguna implementación existente podría continuar compilando correctamente sin cambiar para definir el nuevo método.

El El proyecto Apache Cactus tiene una buena discusión sobre cómo resolver estas obligaciones.

 11
Author: seh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-23 23:58:46

Para responder a su pregunta, sí, podría usar una clase abstracta (sin implementación) en lugar de una interfaz, pero consideraría esta mala práctica:

  • Usted ha agotado su "one-shot" en la herencia (sin obtener ningún beneficio).
  • No puede heredar de múltiples clases abstractas, pero puede implementar múltiples interfaces.

Abogaría por el uso de clases abstractas más en situaciones en las que desea proporcionar una implementación parcial de una clase, posiblemente delegando algún comportamiento a implementaciones de subclases concretas.

 5
Author: Adamski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-23 22:17:23
  • Una clase en java puede heredar de múltiples interfaces, pero solo de una clase abstracta.

  • Una interfaz no puede definir ningún código, en una clase abstracta, puede definir código (es decir, el comportamiento predeterminado de los métodos)

 4
Author: ddccffvv,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-23 22:20:01

Las clases abstractas y las interfaces son complementarias.

Por ejemplo, al crear una API, querrá presentar interfaces al cliente, de modo que siempre pueda cambiar completamente la implementación, mientras que él no tiene que cambiar su código y el usuario no confía en la implementación al compilar utilizando su API, sino solo en los contratos de métodos.

Entonces tendrá clases abstractas que implementan parcialmente estas interfaces, con el fin de

  • compartir algo común código, que podría ser utilizado en todas (o casi todas) las implementaciones de interfaz, lo cual es obvio
  • proporcionar un comportamiento predeterminado que podría ser anulado en implementaciones 'reales', por ejemplo, un método toString() utilizando métodos de interfaces para crear una representación textual de la implementación
  • preservar la compatibilidad de las implementaciones después de los cambios en la interfaz, por ejemplo, cuando agrega un nuevo método en la interfaz, también agrega una implementación predeterminada en la clase abstracta que las implementaciones (por ejemplo las realizadas por el usuario) que extienden la clase abstracta todavía funcionan sin cambios
 4
Author: Guillaume,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-23 23:50:37

Las interfaces son mucho más limpias y ligeras. Las clases abstractas te hacen dependiente de ella en gran medida, ya que no puedes extender ninguna otra clase.

 2
Author: fastcodejava,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-24 09:48:56

Eche un vistazo al interesante artículo " Why extends is evil " para hacerse una idea de las diferencias entre la implementación de la interfaz y la herencia de clases (además de las obvias restricciones multi - single)

 1
Author: bertolami,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-24 10:41:20

¿Qué debería usar, clases abstractas o interfaces?

Considere usar clases abstractas si cualquiera de estas declaraciones se aplica a su situación:

  • desea compartir código entre varias clases estrechamente relacionadas.
  • Se espera que las clases que amplían su clase abstracta tengan muchos métodos o campos comunes, o que requieran modificadores de acceso distintos a los públicos (como protected y private).
  • Desea declarar no estático o campos no definitivos. Esto le permite definir métodos que pueden acceder y modificar el estado del objeto al que pertenecen.

Considere usar interfaces si cualquiera de estas instrucciones se aplica a su situación:

  • Esperas que las clases no relacionadas implementen tu interfaz. Por ejemplo, las interfaces Comparables y Clonables son implementadas por muchas clases no relacionadas.
  • Desea especificar el comportamiento de un tipo de datos en particular, pero no preocupado por quién implementa su comportamiento.
  • Desea aprovechar la herencia múltiple de tipo.

Consulte la documentación de oracle enlace para obtener más detalles

 1
Author: sarath,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-21 14:22:18

Las clases abstractas son la implementación parcial de la Abstracción, mientras que las interfaces son la implementación completa de la Abstracción.Significa que en las clases abstractas podemos poner la declaración de métodos, así como el cuerpo del método. No podemos crear un objeto de clases abstractas(asociación) y reutilizar la clase por herencia (no por asociación). Por defecto en las interfaces todas las variables declaradas son estáticas finales y Todos los métodos son públicos.

Por ejemplo: En JDK solo hay pocas clases abstractas y HttpServlet es uno de ellos que se utiliza en Servlet.So no podemos crear un objeto de HttpServlet y puede ser usado solo por herencia.

 0
Author: Himanshu Mohta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-16 14:08:48

El uso principal de interfaz es cuando se crea la referencia de interfaz y se llama al método de una clase particular que se resuelve en tiempo de ejecución. Así que siempre es mejor idea crear referencia de interfaz para llamar al método.

 0
Author: Darshan Patel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-18 09:36:14

Las interfaces solo pueden contener el método abstracto, también las interfaces pueden implementar múltiples interfaces para cualquier clase. Pero un abstracto sostiene métodos abstractos y no abstractos, y los métodos abstractos no pueden extenderse a más de una clase.

 -1
Author: Justin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-29 09:33:48