¿Cuáles son las diferencias entre las clases abstractas, las interfaces y cuándo usarlas?


15

Recientemente, comencé a entender cómo funciona la OOP, y ahora llego al punto en que cuanto más leo sobre las diferencias entre las clases abstractas y las interfaces, más me confundo. Hasta ahora, ninguno puede ser instanciado. Las interfaces son planos más o menos estructurales que determinan que el esqueleto y los resúmenes son diferentes al poder implementar parcialmente el código.

Me gustaría aprender más sobre estos a través de mi situación específica. Aquí hay un enlace a mi primera pregunta si desea un poco más de información de fondo: ¿Cuál es un buen modelo de diseño para mi nueva clase?

Aquí hay dos clases que creé:

class Ad {
    $title;
    $description
    $price;

    function get_data($website){  }

    function validate_price(){  }
 }


class calendar_event {
    $title;
    $description

    $start_date;

    function get_data($website){ //guts }

    function validate_dates(){ //guts }
 }

Entonces, como puede ver, estas clases son casi idénticas. No se muestran aquí, pero hay otras funciones, like get_zip(), save_to_database()que son comunes en mis clases. También he agregado otras clases Cars y Pets que tienen todos los métodos comunes y, por supuesto, propiedades específicas de esas clases (kilometraje, peso, por ejemplo).

Ahora he violado el principio DRY y estoy administrando y cambiando el mismo código en varios archivos. Tengo la intención de tener más clases como botes, caballos o lo que sea.

Entonces, ¿es aquí donde usaría una interfaz o una clase abstracta? Por lo que entiendo sobre las clases abstractas, usaría una superclase como plantilla con todos los elementos comunes integrados en la clase abstracta, y luego agregaría solo los elementos específicamente necesarios en futuras clases. Por ejemplo:

abstract class content {
    $title;
    $description


    function get_data($website){  }

    function common_function2() { }
    function common_function3() { }
 }


class calendar_event extends content {

    $start_date;

    function validate_dates(){  }
 }

¿O usaría una interfaz y, debido a que son tan similares, crearía una estructura que cada una de las subclases se ve obligada a usar por razones de integridad, y se la dejaría al desarrollador final que desarrolle esa clase para ser responsable de cada una de las subclases? detalles de incluso las funciones comunes. Creo que es posible que algunas funciones 'comunes' deban ajustarse en el futuro para las necesidades de su clase específica.

A pesar de todo lo anterior, si cree que estoy malinterpretando el qué y el por qué de las clases e interfaces abstractas, ¡deje que una respuesta válida deje de pensar en esta dirección y sugiera la forma correcta de avanzar!

¡Gracias!


Hay muchos buenos ejemplos en línea. Creo que este es uno de ellos. javapapers.com/core-java/abstract-and-interface-core-java-2/…
Siva el

Respuestas:


26

En términos simples:

Las interfaces son para el tipo de relaciones "puede hacer / pueden tratarse como" .

Las clases abstractas (así como concretas) son para "es un" tipo de relación.

Mira estos ejemplos:

class Bird extends Animal implements Flight;
class Plane extends Vehicle implements Flight, AccountableAsset;
class Mosquito extends Animal implements Flight;
class Horse extends Animal;
class RaceHorse extends Horse implements AccountableAsset;
class Pegasus extends Horse implements Flight;

Bird, MosquitoY Horse son Animals . Están relacionados. Heredan métodos comunes de Animal like eat(), metabolize() and reproduce(). Tal vez anulan estos métodos, agregando un poco más a ellos, pero aprovechan el comportamiento predeterminado implementado en Animal comometabolizeGlucose().

Planeno está relacionado con Bird, Mosquitoo Horse.

Flightse implementa mediante clases diferentes, no relacionadas, como Birdy Plane.

AccountableAssettambién es implementado por clases diferentes, no relacionadas, como Planey RaceHorse.

Horse no implementa Flight.

Como puede ver, las clases (abstractas o concretas) lo ayudan a construir una jerarquía , permitiéndole heredar código de los niveles superiores a los niveles inferiores de la jerarquía. En teoría, cuanto más bajo está en la jerarquía, más especializado es su comportamiento, pero no tiene que preocuparse por muchas cosas que ya se han solucionado.

Las interfaces , por otro lado, no crean jerarquía, pero pueden ayudar a homogeneizar ciertos comportamientos en las jerarquías para que pueda abstraerlos de la jerarquía en ciertos contextos.

Por ejemplo, puede hacer que un programa sume el valor de un grupo AccountableAssetsindependientemente de su ser RaceHorseso Planes.


Increíble. ¡La interfaz proporciona una cierta sección de funcionalidad que impone can do/can be treated asdónde las clases abstractas actúan como fundamentales!
Abhiroj Panwar

13

Podrías deducir la respuesta lógicamente ya que pareces ser consciente de las diferencias entre los dos.

Las interfaces definen un contrato común. Tal como una interfaz llamada IAnimal, donde todos los animales comparten funciones como Eat (), Move (), Attack () etc. Mientras que todos comparten las mismas funciones, todos o la mayoría de ellos tienen una forma diferente (implementación) de lograr eso.

Las clases abstractas definen una implementación común y, opcionalmente, contratos comunes. Por ejemplo, una calculadora simple podría calificar como una clase abstracta que implementa todos los operadores lógicos y bit a bit básicos y luego se extiende mediante ScientificCalculator, GraphicalCalculator, etc.

Si tiene una implementación común, entonces, por todos los medios, encapsule la funcionalidad en una clase abstracta para ampliarla. Tengo cerca de 0 experiencia PHP, pero no creo que pueda crear interfaces con campos no constantes. Si los campos son comunes entre sus clases de instancia, entonces se ve obligado a usar una clase Abstract, a menos que defina el acceso a ellos a través de getters y setters.

Además, parece que no hay escasez de resultados en Google.


3

Larga historia corta. Las clases abstractas son muy parecidas a las interfaces, ya que ambas proporcionan una plantilla de los métodos que deberían estar dentro de la clase heredada, pero existen grandes diferencias: - Las interfaces solo definen nombres / tipos de métodos que deben existir en una clase heredada, mientras que los abs- las clases pueden tener un código de método predeterminado completo y solo los detalles deben ser anulados. - Las interfaces no pueden tener modificadores de acceso. - Las interfaces no pueden tener campos. - Las clases no pueden tener herencia múltiple de clases, mientras que pueden heredar múltiples interfaces. - Además, las clases proporcionan una estructura jerárquica para que solo las clases derivadas de una clase específica deban seguir las pautas de la clase abstracta: objeto-> objeto específico-> objeto muy específico. Las interfaces, por otro lado, pueden ser heredadas por cualquier persona en cualquier lugar.

En mi opinión, las clases abstractas son más comunes porque pueden proporcionar una implementación predeterminada de código de inmediato, pero en proyectos a gran escala en los que necesita estandarizar ciertas clases, las interfaces pueden ser útiles.

Espero que ayude, pero hay mucha información sobre esto en línea, Leo


2
Classes cannot have multiple inheritance- Es cierto para lenguajes como Java y C #, no es cierto para C ++.
Robert Harvey, el

3

En primer lugar, debe comprender que a menudo proporcionará tanto una interfaz como una clase abstracta. La razón de esto, y la diferencia principal entre los dos, es que le permiten reutilizar un código diferente y así resolver diferentes problemas.

Las interfaces le permiten reutilizar el código del cliente con diferentes implementaciones. Un cliente de su clase get_data ($ sitio web) no se preocupa por los elementos $ title o $ description. Solo quiere indicarle a su contenido que cargue los datos. Si tiene diferentes tipos de contenido, algunos de los cuales necesitan una descripción $ y otros no, puede proporcionar una clase ContentInterface que solo especifique la firma de sus clases secundarias. Ahora el cliente puede tener cualquier cantidad de Contenidos diferentes sin saber exactamente cómo funcionan. El principio de sustitución de liskov es una buena cosa para leer acerca de estudiar esta idea. También me gusta la escritura del tío Bob sobre el tema. Las interfaces son muy importantes para las pruebas unitarias, y crear interfaces es un buen hábito para aprender.

Las clases abstractas le permiten reutilizar detalles de implementación comunes en un conjunto de clases que comparten un antepasado común. En su pregunta, parece tener una buena idea de por qué heredaría la implementación de una clase abstracta. Todavía es peligroso depender de los elementos internos de una clase base: es muy fácil violar la encapsulación y crear niños que dependen de detalles de implementación específicos de una clase base. El patrón de método de plantilla proporciona un ejemplo común y saludable de cómo usar clases base sin violar la encapsulación.

Entonces, como espero haber mostrado, a menudo proporcionará interfaces para los clientes de su jerarquía de clases, de modo que pueda cambiar su implementación de manera segura sin afectar el código del cliente. Esto le permite al cliente escribir pruebas unitarias utilizando Objetos simulados que heredan su interfaz. Y también proporcionará clases abstractas que permiten la reutilización de la lógica común o imponen semántica para las clases secundarias.


3

La diferencia es sutil pero clara. La interfaz trata sobre el comportamiento polimórfico. La clase abstracta trata sobre la reutilización y el comportamiento polimórfico.

Si desea poner énfasis en la reutilización y el comportamiento polimórfico, elija la clase abstracta. Por ejemplo, los diferentes tipos de empleados tienen disposiciones diferentes, pero todos reciben algunos comunes. Entonces, la clase abstracta es adecuada para representarla porque los puntos en común se pueden expresar en una clase abstracta base Employeey la diferencia se puede implementar en clases derivadas como Managero Workeretc.

Si desea poner énfasis solo en el comportamiento polimórfico, elija la interfaz. La interfaz tiene más que ver con el contrato, es decir, un objeto o una jerarquía que dice que se ajusta a cierto comportamiento. Por ejemplo, todos los empleados tienen una provisión de licencia, pero diferentes tipos de empleados tienen diferentes tipos de provisiones. Por lo tanto, cada tipo diferente de empleado requiere una calculadora de licencia diferente. Aquí la interfaz es una buena opción porque todos los tipos de empleados pueden implementar una LeaveCalculatorinterfaz con un Calculate()comportamiento diferente.


-3
  1. La principal diferencia es que los métodos de una interfaz Java son implícitamente abstractos y no pueden tener implementaciones. Una clase abstracta de Java puede tener métodos de instancia que implementen un comportamiento predeterminado.
  2. Las variables declaradas en una interfaz Java son por defecto finales. Una clase abstracta puede contener variables no finales.
  3. Los miembros de una interfaz Java son públicos de forma predeterminada. Una clase abstracta de Java puede tener los sabores habituales de los miembros de la clase como privados, protegidos, etc.
  4. La interfaz Java debe implementarse utilizando la palabra clave "implementos"; Una clase abstracta de Java debe ampliarse con la palabra clave "extiende".
  5. Una interfaz puede extender otra interfaz Java, solo una clase abstracta puede extender otra clase Java e implementar múltiples interfaces Java.
  6. Una clase Java puede implementar múltiples interfaces pero solo puede extender una clase abstracta.
  7. La interfaz es absolutamente abstracta y no puede ser instanciada; Una clase abstracta de Java tampoco se puede instanciar, pero se puede invocar si existe un main ().
  8. En comparación con las clases abstractas de Java, las interfaces de Java son lentas ya que requiere una indirección adicional.
  9. La interfaz y la clase abstracta en Java es que no puede crear un método no abstracto en la interfaz, cada método en la interfaz es abstracto de forma predeterminada, pero puede crear un método no abstracto en la clase abstracta.
  10. La clase abstracta frente a la interfaz en Java es que las interfaces son más adecuadas para la declaración de tipo y la clase abstracta es más adecuada para la reutilización de código y la perspectiva de evolución.
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.