¿Por qué está mal programar en clases abstractas en lugar de interfaces? [cerrado]

Cerrada . Esta pregunta necesita estar más centrada. Actualmente no está aceptando respuestas.
Respuesta 1

¿Problema?

Programar en clase abstracta no es un problema en absoluto, depende de cómo diseñe su relación de objeto.

Diferencia

Abstract Class proporciona una implementación parcial, que promueve la reutilización del código, mientras que Interface solo proporciona métodos sin ninguna implementación que promueva la encapsulación.

Entonces, ¿cuándo usar el resumen?

Debería usar la clase abstracta cuando haya cierta implementación incierta para su subclase y otra parte del comportamiento sea la misma para todas las subclases.

Respuesta: 2

En Java, una de las razones es que no tiene herencia múltiple, por lo que en el momento en que extiende una Clase abstracta, eso es todo, no hay forma de que pueda extender otra.

La única forma de evitar esto es a través de un complejo árbol de dependencias que son muy malas para su arquitectura a largo plazo (será muy difícil descubrir rápidamente qué depende de qué).

Si su clase C necesita exponer la interfaz de la clase abstracta AC (interfaz en el sentido amplio del término), entonces puede hacer que la clase C extienda AC. Pero ahora también desea que su clase C exponga la interfaz de otra clase AC1 ... y no hay una manera simple de hacerlo. Tendrá que recurrir a la composición (que en realidad prefiero a la extensión), o tendrá que hacer que AC1 extienda AC ... o algún otro vudú extraño para que esto funcione.

En mi opinión, la claridad arquitectónica y la extensibilidad son la razón principal por la que uno preferiría usar interfaces en lugar de clases abstractas para componer su solución. También está la cuestión de qué tan robusto puede llegar a ser su código. Si extiende una clase desde un paquete / jar externo, es posible que se quede atascado con esa versión particular de la implementación, ya que los cambios en la clase abstracta pueden romper su código.

Por otra parte...

No todo es perfecto en la tierra del uso de la interfaz. En algunos casos, tratar de ser un purista y usar únicamente interfaces sin ninguna extensión, puede conducir a una duplicación innecesaria de código. Realmente no hay una regla mágica.

Para abordar este problema y mantener la flexibilidad (sin comprometerse con sus únicas extensiones disponibles), puede reutilizar el código a través de la composición en lugar de la herencia. Implemente una interfaz, tenga una clase con el código base común, haga sus métodos "heredados" (de la interfaz), delegue a esa clase común (que se convierte en un atributo de su clase), y tiene lo mejor de ambos mundos.

Finalmente, mi objetivo como desarrollador (particularmente en Java), es poder algún día expresar una opinión que Joshua Bloch no haya expresado mucho mejor antes, hasta el día de hoy, no he podido hacerlo, así que dejo este enlace a Java efectivo, que explica este último punto mucho mejor de lo que soy capaz de:

Java efectivo

Respuesta: 3

Mal podría ser una palabra demasiado fuerte. El contexto siempre importa.

¿Por qué o / o? ¿No puedes hacer las dos cosas? Escriba una interfaz y proporcione una implementación abstracta con comportamiento predeterminado, a la colección java.util.

Solo puede heredar la implementación individualmente; Las interfaces permiten la herencia múltiple. Entonces esa podría ser una razón para preferir las interfaces. Otra es que es posible que no siempre desee un comportamiento predeterminado.

Tome Struts con un grano de sal. Struts 1 fue el primer framework MVC web model-2 en 2000-2002. No tuvo el beneficio de todo lo que se aprendió desde entonces (por ejemplo, Joshua Bloch y "Java efectivo"). Struts 2 no fue una reescritura tan radical, porque tenía que mantener la compatibilidad con versiones anteriores.

No destacaría Struts como un ejemplo de buen diseño o mejores prácticas. Mira a otra parte.

Respuesta: 4

Puede tener lo mejor de ambos mundos si sus clases abstractas implementan una interfaz; en lugar de subclasificar la clase abstracta, puede optar por implementar la interfaz. De esa manera todavía puedes subclasificar otra clase.

Respuesta: 5

no hay nada malo en usar clases abstractas, pero puede que no sea la mejor solución

la clase abstracta puede implementar métodos en parte, mientras que la interfaz no hace nada más que declarar métodos

Cuando tenga sentido para suministrar implementación, use clases abstractas. O haga ambas cosas, defina una interfaz Y (parcialmente) implemente una clase (abstracta) que implemente esta interfaz

Respuesta: 6

En pocas palabras y conceptualmente, a menudo se describe como:

  • clases abstractas: IS-A
  • interfaces: HAS-A (o can-do, -able ...)

Ejemplo: la clase Perro y la clase Gato extienden la clase abstracta Animal, porque ambos son animales (el perro es un animal). La clase abstracta Animal tendría métodos como walk () o sleep (). Class Animal puede implementar la interfaz Washable con un método wash (). Este método se implementaría para cada animal, ya que uno usaría barro, agua, su lengua, los dedos de su compañero mono ...

Como se ha dicho, las interfaces permiten más modularidad. Se prefieren en proyectos grandes ya que permite menos saltos de código e implementaciones simuladas. (Ej. Tengo que usar un servicio tuyo pero no tuviste suficiente tiempo para implementarlo. Si usamos una interfaz, puedo crear este simulacro con el método getProductId () que siempre devuelve el mismo número. Cuando habrás terminado, sustituimos mi burla por tu servicio real). Los simulacros son excelentes para fines de prueba.

Ejemplos prácticos:

Respuesta: 7

Tengo una lista de objetos que contiene diferentes tipos de objetos, pero una sola propiedad es común entre todos. La lista contiene objetos de clase de campo, clase de botón, clase de página, etc. pero una propiedad es ...

Actualización: Respondí mi propia pregunta aquí: Escanear classpath / modulepath en tiempo de ejecución en Java 9 - [Pregunta anterior - obsoleta:] En el sistema de módulos Java 9, puede encontrar módulos del sistema usando Set <...

Las "lecturas sucias", que significan leer el valor de un objeto a pesar de que está bloqueado por otro hilo, se describen en el sitio web de Terracotta, sin embargo, he oído que no deberían usarse, incluso si usted no ...

¿Cuál es la vida de un objeto Java al que se le pasa un argumento de método? Por ejemplo, tengo un objeto Test class Test {public string testType () {.....}} y tengo dos clases A y B ...