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

14

Recientemente, comencé a envolver mi cabeza en torno a la POO, y ahora estoy en el punto en el que cuanto más leo sobre las diferencias entre clases abstractas e interfaces, más confuso estoy. Hasta ahora, ninguno puede ser instanciado. Las interfaces son planos más o menos estructurales que determinan el esqueleto y los resúmenes son diferentes al poder implementar parcialmente el código.

Me gustaría aprender más sobre esto 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: ¿Qué 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 puedes ver, estas clases son casi idénticas. No se muestra aquí, pero hay otras funciones, like get_zip() , save_to_database() que son comunes en mis clases. También he agregado otras clases de automóviles y mascotas 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 barcos, 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 súper clase como plantilla con todos los elementos comunes integrados en la clase abstracta y luego agregaría solo los elementos que se necesitan específicamente en las clases futuras. 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á una estructura que cada una de las subclases está obligada a usar por razones de integridad, y la deja en manos del desarrollador final que descargue esa clase para que sea responsable de Cada uno de los detalles de incluso las funciones comunes. Creo que es posible que algunas funciones "comunes" deban modificarse en el futuro para las necesidades de su clase específica.

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

¡Gracias!

    
pregunta user66662 04.11.2012 - 00:38
fuente

6 respuestas

24

En términos sencillos:

Interfaces son para "puede hacer / puede tratarse como" tipo de relaciones.

Las clases abstractas (así como las 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 , Mosquito y Horse son Animals . Están relacionados. Heredan métodos comunes de animales como eat(), metabolize() and reproduce() . Quizás anulen estos métodos, agregándoles un poco más de ellos, pero aprovechan el comportamiento predeterminado implementado en Animal como metabolizeGlucose().

Plane no está relacionado con Bird , Mosquito o Horse .

Flight se implementa mediante clases diferentes, no relacionadas, como Bird y Plane .

AccountableAsset también se implementa mediante clases diferentes, no relacionadas, como Plane y RaceHorse .

Horse no implementa Flight.

Como puede ver clases (resumen o concreto) le ayuda a crear jerarquías , permitiéndole heredar código desde 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 será su comportamiento, pero no tendrá que preocuparse por muchas cosas que ya se han resuelto.

Interfaces , por otro lado, no crea una jerarquía, pero pueden ayudar a homogeneizar ciertos comportamientos entre 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 de AccountableAssets independientemente de que sean RaceHorses o Planes .

    
respondido por el Tulains Córdova 04.11.2012 - 03:04
fuente
13

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

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

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

Si tiene una implementación común, entonces, por supuesto, encapsule la funcionalidad en una clase abstracta para extenderla. Tengo cerca de 0 experiencia de PHP, pero no creo que pueda crear interfaces con campos no constantes. Si los campos son comunes entre las clases de su instancia, entonces están obligados a usar una clase abstracta, a menos que defina el acceso a ellos a través de captadores y definidores.

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

    
respondido por el Dante 04.11.2012 - 02:09
fuente
3

Larga historia corta. Las clases abstractas son muy parecidas a las interfaces, ya que ambas proporcionan una plantilla de los métodos que deben estar dentro de la clase hereditaria, pero hay grandes diferencias: - Las interfaces solo definen nombres / tipos de métodos que deben existir en una clase hereditaria, mientras que las clases de abs pueden tener un código de método predeterminado completo y solo es posible que se deban sobreescribir los detalles. - 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 interfaces múltiples. - Además, las clases proporcionan una estructura jerárquica de modo que solo las clases derivadas de una clase específica deben seguir las pautas de la clase abstracta: objeto específico > objeto específico > Objeto muy específico. Las interfaces por otro lado pueden ser heredadas por cualquiera 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 es necesario estandarizar ciertas clases, las interfaces pueden ser útiles.

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

    
respondido por el RealityDysfunction 04.11.2012 - 01:09
fuente
3

En primer lugar, debe comprender que a menudo proporcionará una interfaz y 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. A un cliente de su clase get_data ($ website) no le importan los elementos $ title o $ description. Solo quiere dar instrucciones a tu contenido para que cargue los datos. Si tiene diferentes tipos de contenido, algunos de los cuales necesitan una descripción de $ y otros que no, puede proporcionar una clase ContentInterface que solo especifique la firma de sus clases secundarias. Ahora el cliente puede tener cualquier número de Contenidos diferentes sin que todos sepan 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 escribir 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 ancestro común. En su pregunta, parece que tiene un buen control sobre por qué heredaría la implementación de una clase abstracta. Aún es peligroso depender de los elementos internos de una clase base; es muy fácil violar la encapsulación y crear hijos que dependen de los 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 puede cambiar su implementación de manera segura sin afectar el código del cliente. Esto le permite al cliente escribir pruebas unitarias utilizando Mock Objects que heredan su interfaz. Y también proporcionará clases abstractas que permitan reutilizar la lógica común o imponer la semántica para las clases secundarias.

    
respondido por el Ben 04.11.2012 - 02:31
fuente
3

La diferencia es sutil pero clara. La interfaz es 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, diferentes tipos de empleados tienen diferentes disposiciones, pero todos reciben algunos comunes. Por lo tanto, la clase abstracta es adecuada para representarla porque las similitudes se pueden expresar en una clase abstracta base Employee y la diferencia se puede implementar en clases derivadas como Manager o Worker etc.

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 jerarquía que dice que se ajusta a cierto comportamiento. Por ejemplo, todos los empleados tienen provisiones de licencia, pero los diferentes tipos de empleados tienen diferentes tipos de provisiones. Entonces, 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 interfaz LeaveCalculator con un comportamiento Calculate() diferente.

    
respondido por el theD 04.11.2012 - 04:18
fuente
-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 implementan 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 de Java son públicos de forma predeterminada. Una clase abstracta de Java puede tener los sabores habituales de los miembros de la clase como privado, protegido, etc.
  4. La interfaz de Java debe implementarse utilizando "implementos" de palabras clave; Una clase abstracta de Java debe extenderse usando la palabra clave "extiende".
  5. Una interfaz puede extender otra interfaz de Java, solo una clase abstracta puede extender otra clase de Java e implementar múltiples interfaces de Java.
  6. Una clase Java puede implementar múltiples interfaces pero puede extender solo una clase abstracta.
  7. La interfaz es absolutamente abstracta y no puede ser instanciada; Una clase abstracta de Java tampoco se puede crear una instancia, 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 requieren una dirección indirecta adicional.
  9. La interfaz y la clase abstracta en Java es que no puede crear un método no abstracto en la interfaz, todos los métodos en la interfaz son, por defecto, abstractos, 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 la evolución.
respondido por el Sakina.A 06.02.2013 - 15:48
fuente

Lea otras preguntas en las etiquetas