¿Cuál es la diferencia entre una interfaz y una clase abstracta?

1753

¿Cuál es exactamente la diferencia entre una interfaz y una clase abstracta?

Sarfraz
fuente
96
Esta es una pregunta de entrevista extremadamente común. Es sorprendente ya que una clase abstracta rara vez se usa en soluciones en comparación con otras cosas. Tu pregunta me ha ayudado Safraz.
Catto
55
Esta pregunta también podría ayudar a comprender el concepto de interfaces stackoverflow.com/q/8531292/1055241
gprathour
66
He eliminado la etiqueta PHP de esta pregunta, ya que casi ninguna de las respuestas es específica del idioma, y ​​la pregunta en sí no es específica del idioma.
brice
2
En el pasado, en c ++, una interfaz es una clase base abstracta pura con todas las implementaciones de métodos = 0. Si un solo método no era = 0, entonces tiene una implementación y la base abstracta ya no es pura y ya no es una interfaz . Creo que el VMT tiene menos indirección cuando la herencia múltiple usa solo bases abstractas puras, pero ya no recuerdo cómo se ven, ha pasado demasiado tiempo.
Jim

Respuestas:

2255

Interfaces

Una interfaz es un contrato : la persona que escribe la interfaz dice: " hey, acepto que las cosas se vean de esa manera ", y la persona que usa la interfaz dice " OK, la clase que escribo se ve de esa manera ".

Una interfaz es un shell vacío . Solo existen las firmas de los métodos, lo que implica que los métodos no tienen cuerpo. La interfaz no puede hacer nada. Es solo un patrón.

Por ejemplo (pseudocódigo):

// I say all motor vehicles should look like this:
interface MotorVehicle
{
    void run();

    int getFuel();
}

// My team mate complies and writes vehicle looking that way
class Car implements MotorVehicle
{

    int fuel;

    void run()
    {
        print("Wrroooooooom");
    }


    int getFuel()
    {
        return this.fuel;
    }
}

La implementación de una interfaz consume muy poca CPU, porque no es una clase, solo un montón de nombres y, por lo tanto, no hay ninguna búsqueda costosa que hacer. Es genial cuando importa, como en dispositivos integrados.


Clases abstractas

Las clases abstractas, a diferencia de las interfaces, son clases. Son más caros de usar, porque hay que buscarlos cuando heredas de ellos.

Las clases abstractas se parecen mucho a las interfaces, pero tienen algo más: puede definir un comportamiento para ellas. Se trata más bien de una persona que dice, " estas clases deberían verse así, y tienen eso en común, ¡así que complete los espacios en blanco! ".

Por ejemplo:

// I say all motor vehicles should look like this:
abstract class MotorVehicle
{

    int fuel;

    // They ALL have fuel, so lets implement this for everybody.
    int getFuel()
    {
         return this.fuel;
    }

    // That can be very different, force them to provide their
    // own implementation.
    abstract void run();
}

// My teammate complies and writes vehicle looking that way
class Car extends MotorVehicle
{
    void run()
    {
        print("Wrroooooooom");
    }
}

Implementación

Si bien se supone que las clases abstractas y las interfaces son conceptos diferentes, las implementaciones hacen que esa afirmación a veces sea falsa. A veces, ni siquiera son lo que crees que son.

En Java, esta regla se aplica con fuerza, mientras que en PHP, las interfaces son clases abstractas sin ningún método declarado.

En Python, las clases abstractas son más un truco de programación que puedes obtener del módulo ABC y en realidad están usando metaclases y, por lo tanto, clases. Y las interfaces están más relacionadas con la escritura de pato en este lenguaje y es una mezcla entre convenciones y métodos especiales que llaman descriptores (los métodos __method__).

Como es habitual con la programación, hay teoría, práctica y práctica en otro idioma :-)

e-satis
fuente
66
El punto clave sobre las interfaces no es tanto que digan lo que hace una clase, sino que permiten que los objetos que pueden Wizzle sean útiles para el código que necesita un Wizzler. Tenga en cuenta que en muchos casos ni la persona que escribe lo que puede Wizzle, ni la persona que necesita un Wizzler, será la persona que escriba la interfaz.
supercat
187
No creo que el consumo de CPU sea el punto destacado de las interfaces.
Dan Lugg
55
@ e-satis ¿Puede explicar su punto sobre la utilización de la CPU? ¿Por qué la clase abstracta como clase aumenta la utilización de la CPU? ¿A qué tipo de búsqueda te refieres aquí?
Geek
36
@ e-satis Con Java 8, puede definir métodos predeterminados en las interfaces, lo que equivale a tener métodos no abstractos en clases abstractas. Con esta adición, ya no puedo ver la diferencia real entre las clases abstractas y la interfaz además del hecho de que debería usar interfaces porque las clases pueden implementar múltiples interfaces pero solo pueden heredar una clase
Ogen
23
Creo que la comparación entre interfacey classdesde Head First Javaes vívida queA class defines who you are, and an interface tells what roles you could play
LittleLittleQ
872

Las principales diferencias técnicas entre una clase abstracta y una interfaz son:

  • Las clases abstractas pueden tener constantes, miembros, stubs de método (métodos sin cuerpo) y métodos definidos , mientras que las interfaces solo pueden tener constantes y stubs de métodos .

  • Los métodos y los miembros de una clase abstracta se pueden definir con cualquier visibilidad , mientras que todos los métodos de una interfaz se deben definir como public(se definen como públicos de forma predeterminada).

  • Al heredar una clase abstracta, una clase secundaria concreta debe definir los métodos abstractos , mientras que una clase abstracta puede extender otra clase abstracta y los métodos abstractos de la clase principal no tienen que definirse.

  • Del mismo modo, una interfaz que extiende otra interfaz no es responsable de implementar métodos desde la interfaz principal. Esto se debe a que las interfaces no pueden definir ninguna implementación.

  • Una clase secundaria solo puede extender una sola clase (abstracta o concreta), mientras que una interfaz puede extender o una clase puede implementar varias otras interfaces .

  • Una clase secundaria puede definir métodos abstractos con la misma visibilidad o menos restrictiva , mientras que una clase que implementa una interfaz debe definir los métodos con exactamente la misma visibilidad (pública).

Justin Johnson
fuente
123
Creo que esta es la mejor respuesta porque destaca todas las diferencias clave. Un ejemplo no es realmente necesario.
Joshua K
44
Y normalmente con las clases puede crear una instancia de un objeto a diferencia de las clases abstractas que CANNOTse instancian.
SASM
Pensé que una clase que implementa la interfaz necesita definir todos los métodos en la interfaz.
Usuario de Jiazzy el
@Jiazzyuser Si una clase abstracta implementa una interfaz, no tiene que definir realmente los métodos de la interfaz. Ese requisito se puede diferir a heredar / clases concretas secundarias. Sin embargo, una clase concreta debe implementar todos los métodos de interfaz que su clase principal no implementa. Agregaré un ejemplo para ilustrar este punto.
Justin Johnson
55
"Al heredar una clase abstracta, la clase secundaria debe definir los métodos abstractos, mientras que una interfaz puede extender otra interfaz y los métodos no tienen que definirse". - Esto no es verdad. Así como una interfaz puede extender una interfaz sin definir métodos, una clase abstracta puede heredar una clase abstracta sin definir métodos.
Nick
141

Una interfaz contiene solo la definición / firma de funcionalidad, y si tenemos alguna funcionalidad común así como firmas comunes, entonces necesitamos usar una clase abstracta. Al usar una clase abstracta, podemos proporcionar comportamiento y funcionalidad al mismo tiempo. Otro desarrollador que herede la clase abstracta puede usar esta funcionalidad fácilmente, ya que solo necesitarían completar los espacios en blanco.

ingrese la descripción de la imagen aquí Tomado de:

http://www.dotnetbull.com/2011/11/difference-between-abstract-class-and.html

http://www.dotnetbull.com/2011/11/what-is-abstract-class-in-c-net.html http://www.dotnetbull.com/2011/11/what-is-interface-in -c-net.html

Vivek
fuente
17
Debe decir a qué idioma se aplica esto ("La clase abstracta no admite herencia múltiple" está lejos de ser universalmente cierto)
Ben Voigt
¡La última comparación es confusa según la tabla! Los métodos en la interfaz no pueden ser estáticos, pero las variables son estáticas finales Los métodos implementados en la clase abstracta pueden ser estáticos
realPK
8
El miembro de la interfaz debe ser estático final. La última afirmación es incorrecta.
Jawad Zeb
Creo que "funcionalidad" en esta respuesta significa "implementación". ¿No está seguro de lo que significa "comportamiento", tal vez "firmas"?
LarsH
2
¿Cuál es el lenguaje de programación dirigido aquí? C#?
Peter Mortensen
80

Puede encontrar una explicación aquí: http://www.developer.com/lang/php/article.php/3604111/PHP-5-OOP-Interfaces-Abstract-Classes-and-the-Adapter-Pattern.htm

Una clase abstracta es una clase que solo el programador implementa parcialmente. Puede contener uno o más métodos abstractos. Un método abstracto es simplemente una definición de función que sirve para decirle al programador que el método debe implementarse en una clase secundaria.

Una interfaz es similar a una clase abstracta; de hecho, las interfaces ocupan el mismo espacio de nombres que las clases y las clases abstractas. Por esa razón, no puede definir una interfaz con el mismo nombre que una clase. Una interfaz es una clase completamente abstracta; ninguno de sus métodos se implementa y, en lugar de una subclase de clase, se dice que implementa esa interfaz.

De todos modos, encuentro esta explicación de las interfaces algo confusa. Una definición más común es: una interfaz define un contrato que las clases de implementación deben cumplir. Una definición de interfaz consiste en firmas de miembros públicos, sin ningún código de implementación.

Konamiman
fuente
44
Esta es la respuesta más correcta, ya que las interfaces PHP difieren de otros lenguajes en que las interfaces PHP SON clases abstractas bajo el capó, mientras que las interfaces de otros lenguajes son firmas que las clases deben coincidir. Sin embargo, se comportan igual siempre que no haya errores.
Tor Valamo
1
Es cierto que para PHP es la mejor respuesta real. Pero es más difícil de obtener del blob de texto que de un simple fragmento.
e-satis
A partir de las definiciones que proporcionó, se ven iguales excepto por un detalle: y la interfaz es 100% abstracta, mientras que una clase abstracta es parcialmente abstracta y puede tener algunas implementaciones de métodos (¿quizás todos los métodos pueden tener implementaciones?).
jww
41

No quiero resaltar las diferencias, que ya se han dicho en muchas respuestas (con respecto a modificadores finales estáticos públicos para variables en interfaz y soporte para métodos privados protegidos en clases abstractas)

En términos simples, me gustaría decir:

interfaz: para implementar un contrato por varios objetos no relacionados

clase abstracta: para implementar el mismo comportamiento o diferente entre varios objetos relacionados

De la documentación de Oracle

Considere usar clases abstractas si:

  1. Desea compartir código entre varias clases estrechamente relacionadas.
  2. Espera que las clases que extienden su clase abstracta tengan muchos métodos o campos comunes, o requieran modificadores de acceso que no sean públicos (como protegidos y privados).
  3. Desea declarar campos no estáticos o no finales.

Considere usar interfaces si:

  1. Espera que clases no relacionadas implementen su interfaz. Por ejemplo, muchos objetos no relacionados pueden implementar la Serializableinterfaz.
  2. Desea especificar el comportamiento de un tipo de datos en particular, pero no le preocupa quién implementa su comportamiento.
  3. Desea aprovechar la herencia múltiple de tipo.

clase abstracta establece "es una" relación con clases concretas. La interfaz proporciona "tiene una" capacidad para las clases.

Si está buscando un Javalenguaje de programación, aquí hay algunas actualizaciones más:

Java 8 ha reducido la brecha entre las clases interfacey abstracthasta cierto punto al proporcionar una defaultfunción de método. Una interfaz que no tiene una implementación para un método ya no es válida.

Consulte esta página de documentación para más detalles.

Eche un vistazo a esta pregunta SE para ver ejemplos de código para comprender mejor.

¿Cómo debería haber explicado la diferencia entre una interfaz y una clase abstracta?

Ravindra babu
fuente
38

Algunas diferencias importantes:

En forma de tabla:

Diferencia

Como lo dijo Joe de javapapers :

1.La diferencia principal 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 por defecto. 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 extenderse utilizando la palabra clave "extiende".

5. Una interfaz solo puede extender otra interfaz Java, 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.

softmage99
fuente
3
He editado su respuesta para proporcionar la atribución correcta. No puede simplemente soltar un enlace en la parte inferior de su respuesta. También debe citar todo el idioma que se copió de otra fuente. Además, si esa tabla se extrajo de algún lugar, debe indicar claramente de dónde es.
Brad Larson
Mencione también para C ++ ... aunque no hay una palabra clave "interfaz" en C ++ como tal, pero también es un Qn regd C ++ comúnmente preguntado.
cbinder
@cbinder: No hay una palabra clave 'interfaz' en c ++. Para conocer la diferencia en c ++, consulte 1. tutorialspoint.com/cplusplus/cpp_interfaces.htm 2. tutorialspoint.com/cplusplus/cpp_interfaces.htm
softmage99
@MageshBabu Quizás definir una función en una clase que contiene una función virtual pura la convierte en una clase abstracta en lugar de la interfaz
cbinder
2
Con Java 8, las diferencias son menores ahora. Verifique las diferencias actualizadas aquí: journaldev.com/1607/…
Pankaj
31

El punto principal es que:

  • El resumen está orientado a objetos . Ofrece los datos básicos que un 'objeto' debería tener y / o funciones que debería poder hacer. Tiene que ver con las características básicas del objeto: lo que tiene y lo que puede hacer. Por lo tanto, los objetos que heredan de la misma clase abstracta comparten las características básicas (generalización).
  • La interfaz está orientada a la funcionalidad . Define las funcionalidades que un objeto debe tener. Independientemente de qué objeto sea, siempre que pueda hacer estas funcionalidades, que están definidas en la interfaz, está bien. Ignora todo lo demás. Un objeto / clase puede contener varias (grupos de) funcionalidades; por lo tanto, es posible que una clase implemente múltiples interfaces.
Moch Yusup
fuente
Gracias ahora estamos llegando a un lugar con una buena respuesta de alto nivel. Es curioso cuán profundo en los comentarios tienes que ir para encontrar una respuesta más basada en la comprensión.
Andrew
1
Las otras respuestas son demasiado técnicas. Esto se está acercando a lo que sentiría como una respuesta "correcta". El objetivo principal de OOP es la semántica, y si las clases anidadas privadas se invocan o no a los captadores públicos a través de búsquedas costosas de CPU es casi irrelevante aquí
Sentinel
26

Cuando desee proporcionar un comportamiento polimórfico en una jerarquía de herencia, use clases abstractas.

Cuando desee un comportamiento polimórfico para clases que no están relacionadas, use una interfaz.

escultor
fuente
24

Estoy construyendo un edificio de 300 pisos.

La interfaz de planos del edificio

  • Por ejemplo, Servlet (I)

Edificio construido hasta 200 pisos - parcialmente completado --- resumen

  • Implementación parcial, por ejemplo, servlet genérico y HTTP

Construcción de edificios terminada - hormigón

  • Implementación completa, por ejemplo, servlet propio

Interfaz

  • No sabemos nada sobre la implementación, solo los requisitos. Podemos ir por una interfaz.
  • Cada método es público y abstracto por defecto
  • Es una clase abstracta 100% pura
  • Si declaramos público no podemos declarar privado y protegido
  • Si declaramos abstracto no podemos declarar final, estático, sincronizado, estricto fp y nativo
  • Cada interfaz tiene public, static y final
  • La serialización y transitorios no son aplicables, porque no podemos crear una instancia para la interfaz
  • No volátil porque es final
  • Cada variable es estática.
  • Cuando declaramos una variable dentro de una interfaz, necesitamos inicializar variables mientras declaramos
  • Instancia y bloqueo estático no permitidos

Resumen

  • Implementación parcial
  • Tiene un método abstracto. Además, utiliza hormigón
  • Sin restricción para modificadores de método de clase abstracta
  • Sin restricción para modificadores variables de clase abstracta
  • No podemos declarar otros modificadores excepto el abstracto
  • Sin restricción para inicializar variables

Tomado del sitio web DurgaJobs

Jaichander
fuente
Una clase abstracta puede tener un constructor
vimal krishna
44
Estoy completamente en desacuerdo con esta opinión. El plan es un concepto completamente diferente de "interfaz". Blueprint es más análogo a un modelo estático o especificación de diseño para una implementación específica. Está más cerca de la 'clase', ya que el plano se puede instanciar varias veces a través de su constructor, pero incluso esto no está lo suficientemente cerca, ya que la 'clase' también contiene la especificación de cómo construir (el ctor) y los medios para hacerlo. entonces. La interfaz como concepto está destinada a representar algunos comportamientos, como Calentamiento / Enfriamiento, que se pueden aplicar a una variedad de cosas, por ejemplo: edificios, hornos, etc.
Sentinel
18

Trabajemos en esta pregunta nuevamente:

Lo primero que debe hacerle saber es que 1/1 y 1 * 1 dan como resultado lo mismo, pero no significa que la multiplicación y la división sean iguales. Obviamente, mantienen una buena relación, pero tenga en cuenta que ambos son diferentes.

Señalaré las principales diferencias, y el resto ya se ha explicado:

Las clases abstractas son útiles para modelar una jerarquía de clases. A primera vista de cualquier requisito, tenemos parcialmente claro qué es exactamente lo que se debe construir, pero sabemos qué construir.Y entonces tus clases abstractas son tus clases base.

Las interfaces son útiles para permitir que otras jerarquías o clases sepan lo que soy capaz de hacer. Y cuando dices que soy capaz de algo, debes tener esa capacidad. Las interfaces lo marcarán como obligatorio para que una clase implemente las mismas funcionalidades.

Dhananjay
fuente
2
Buena respuesta, pero la metáfora matemática es inútil y me hizo perder aproximadamente una cantidad equivalente de tiempo leyéndola mientras escribía este comentario. Ahora multiplique eso por todas las otras personas que han leído esta pregunta.
Andrew
"la metáfora matemática es inútil", ¿por qué piensas eso?
Dhananjay
12

Es bastante simple en realidad.

Puede pensar en una interfaz como una clase que solo puede tener métodos abstractos y nada más.

Por lo tanto, una interfaz solo puede "declarar" y no definir el comportamiento que desea que tenga la clase.

Una clase abstracta le permite declarar (usando métodos abstractos) y definir (usando implementaciones de métodos completos) el comportamiento que desea que tenga la clase.

Y una clase regular solo le permite definir, no declarar, el comportamiento / acciones que desea que tenga la clase.

Una última cosa,

En Java, puede implementar varias interfaces, pero solo puede extender una (Clase abstracta o Clase) ...

Esto significa que la herencia del comportamiento definido está restringida para permitir solo uno por clase ... es decir, si desea una clase que encapsule el comportamiento de las Clases A, B y C, deberá hacer lo siguiente: La clase A se extiende B, la Clase C se extiende A ... es un poco redondo sobre la forma de tener herencia múltiple ...

Las interfaces, por otro lado, simplemente podría hacer: la interfaz C implementa A, B

Entonces, en efecto, Java admite herencia múltiple solo en "comportamiento declarado", es decir, interfaces, y solo herencia única con comportamiento definido ... a menos que haga la ronda de la manera que describí ...

Esperemos que tenga sentido.

g00dnatur3
fuente
11

La comparación de la interfaz frente a la clase abstracta es incorrecta. Debería haber otras dos comparaciones en su lugar: 1) interfaz vs. clase y 2) resumen vs. clase final .

Interfaz vs clase

La interfaz es un contrato entre dos objetos. Por ejemplo, soy cartero y tú eres un paquete para entregar. Espero que sepas tu dirección de entrega. Cuando alguien me da un Paquete, tiene que saber su dirección de entrega:

interface Package {
  String address();
}

La clase es un grupo de objetos que obedecen el contrato. Por ejemplo, soy una caja del grupo "Caja" y obedezco el contrato requerido por el Cartero. Al mismo tiempo obedezco otros contratos:

class Box implements Package, Property {
  @Override
  String address() {
    return "5th Street, New York, NY";
  }
  @Override
  Human owner() {
    // this method is part of another contract
  }
}

Resumen vs final

La clase abstracta es un grupo de objetos incompletos. No se pueden usar porque faltan algunas partes. Por ejemplo, soy un cuadro abstracto compatible con GPS: sé cómo verificar mi posición en el mapa:

abstract class GpsBox implements Package {
  @Override
  public abstract String address();
  protected Coordinates whereAmI() {
    // connect to GPS and return my current position
  }
}

Esta clase, si es heredada / extendida por otra clase, puede ser muy útil. Pero por sí mismo, es inútil, ya que no puede tener objetos. Las clases abstractas pueden ser elementos de construcción de las clases finales.

La clase final es un grupo de objetos completos, que se pueden usar, pero no se pueden modificar. Saben exactamente cómo trabajar y qué hacer. Por ejemplo, soy un cuadro que siempre va a la dirección especificada durante su construcción:

final class DirectBox implements Package {
  private final String to;
  public DirectBox(String addr) {
    this.to = addr;
  }
  @Override
  public String address() {
    return this.to;
  }
}

En la mayoría de los lenguajes, como Java o C ++, es posible tener solo una clase , ni abstracta ni final. Tal clase puede ser heredada y puede ser instanciada. Sin embargo, no creo que esto esté estrictamente en línea con el paradigma orientado a objetos.

Nuevamente, comparar interfaces con clases abstractas no es correcto.

yegor256
fuente
9

En resumen, las diferencias son las siguientes:

Diferencias sintácticas entre interfaz y clase abstracta :

  1. Los métodos y los miembros de una clase abstracta pueden tener cualquier visibilidad. Todos los métodos de una interfaz deben ser públicos . // Ya no es verdad desde Java 9
  2. Una clase secundaria concreta de una clase abstracta debe definir todos los métodos abstractos. Una clase secundaria abstracta puede tener métodos abstractos. Una interfaz que extiende otra interfaz no necesita proporcionar una implementación predeterminada para los métodos heredados de la interfaz principal.
  3. Una clase secundaria solo puede extender una sola clase. Una interfaz puede extender múltiples interfaces. Una clase puede implementar múltiples interfaces.
  4. Una clase secundaria puede definir métodos abstractos con la misma visibilidad o menos restrictiva, mientras que la clase que implementa una interfaz debe definir todos los métodos de la interfaz como públicos.
  5. Las clases abstractas pueden tener constructores pero no interfaces .
  6. Las interfaces de Java 9 tienen métodos estáticos privados.

En Interfaces ahora:

public static- compatible
public abstract- compatible
public default- compatible
private static- compatible
private abstract- error de
private defaultcompilación
private- error de compilación - compatible

Pritam Banerjee
fuente
8

La única diferencia es que uno puede participar en la herencia múltiple y el otro no.

La definición de una interfaz ha cambiado con el tiempo. ¿Crees que una interfaz solo tiene declaraciones de métodos y son solo contratos? ¿Qué pasa con las variables finales estáticas y las definiciones predeterminadas después de Java 8?

Las interfaces se introdujeron en Java debido al problema del diamante con herencia múltiple y eso es lo que realmente pretenden hacer.

Las interfaces son las construcciones que se crearon para salirse con el problema de la herencia múltiple y pueden tener métodos abstractos, definiciones predeterminadas y variables finales estáticas.

Consulte ¿Por qué Java permite variables finales estáticas en las interfaces cuando solo están destinadas a ser contratos? .

Vivek Vermani
fuente
1
Si bien esa es una diferencia importante , esa no es la única diferencia.
Govind Parmar
7

Interfaz: gire (gire a la izquierda, gire a la derecha).

Clase abstracta: rueda.

Clase: Volante, deriva de la rueda, expone la interfaz de giro

Uno es para clasificar el comportamiento que se puede ofrecer en una amplia gama de cosas, el otro es para modelar una ontología de las cosas.

Centinela
fuente
6

Si tiene algunos métodos comunes que pueden ser utilizados por múltiples clases, vaya a clases abstractas. De lo contrario, si desea que las clases sigan un plan definido, vaya a las interfaces.

Los siguientes ejemplos demuestran esto.

Clase abstracta en Java:

abstract class animals
{
    // They all love to eat. So let's implement them for everybody
    void eat()
    {
        System.out.println("Eating...");
    }
    // The make different sounds. They will provide their own implementation.
    abstract void sound();
}

class dog extends animals
{
    void sound()
    {
        System.out.println("Woof Woof");
    }
}

class cat extends animals
{
    void sound()
    {
        System.out.println("Meoww");
    }
}

A continuación se muestra una implementación de la interfaz en Java:

interface Shape
{
    void display();
    double area();
}

class Rectangle implements Shape 
{
    int length, width;
    Rectangle(int length, int width)
    {
        this.length = length;
        this.width = width;
    }
    @Override
    public void display() 
    {
        System.out.println("****\n* *\n* *\n****"); 
    }
    @Override
    public double area() 
    {
        return (double)(length*width);
    }
} 

class Circle implements Shape 
{
    double pi = 3.14;
    int radius;
    Circle(int radius)
    {
        this.radius = radius;
    }
    @Override
    public void display() 
    {
        System.out.println("O"); // :P
    }
    @Override
    public double area() 
    { 
        return (double)((pi*radius*radius)/2);
    }
}

Algunos puntos clave importantes en pocas palabras:

  1. Las variables declaradas en la interfaz Java son por defecto finales. Las clases abstractas pueden tener variables no finales.

  2. Las variables declaradas en la interfaz Java son por defecto estáticas. Las clases abstractas pueden tener variables no estáticas.

  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.

Pransh Tiwari
fuente
4

Muchos desarrolladores junior cometen el error de pensar que las interfaces, las clases abstractas y concretas son pequeñas variaciones de la misma cosa, y eligen una de ellas únicamente por razones técnicas: ¿Necesito herencia múltiple? ¿Necesito algún lugar para poner métodos comunes? ¿Debo molestarme con algo más que una clase concreta? Esto está mal, y oculto en estas preguntas está el principal problema: "Yo" . Cuando escribes código para ti, por ti mismo, rara vez piensas en otros desarrolladores presentes o futuros trabajando en o con tu código.

Las interfaces y las clases abstractas, aunque aparentemente son similares desde un punto de vista técnico, tienen significados y propósitos completamente diferentes.

Resumen

  1. Una interfaz define un contrato que alguna implementación cumplirá para usted .

  2. Una clase abstracta proporciona un comportamiento predeterminado que su implementación puede reutilizar.

Resumen alternativo

  1. Una interfaz es para definir API públicas
  2. Una clase abstracta es para uso interno y para definir SPI

Sobre la importancia de ocultar detalles de implementación

Una clase concreta hace el trabajo real, de una manera muy específica. Por ejemplo, un ArrayListusa un área contigua de memoria para almacenar una lista de objetos de manera compacta que ofrece acceso aleatorio rápido, iteración y cambios en el lugar, pero es terrible en las inserciones, eliminaciones y ocasionalmente incluso en adiciones; Mientras tanto, un LinkedListutiliza nodos de doble enlace para almacenar una lista de objetos, que en su lugar ofrece iteración rápida, cambios en el lugar e inserción / eliminación / adición, pero es terrible en el acceso aleatorio. Estos dos tipos de listas están optimizados para diferentes casos de uso, y es muy importante cómo los usará. Cuando intentas exprimir el rendimiento de una lista con la que estás interactuando mucho, y cuando eliges el tipo de lista, debes elegir con cuidado cuál estás creando una instancia.

Por otro lado, a los usuarios de alto nivel de una lista realmente no les importa cómo se implementa realmente, y deberían estar aislados de estos detalles. Imaginemos que Java no expuso la Listinterfaz, sino que solo tenía una Listclase concreta que en realidad LinkedListes lo que es ahora. Todos los desarrolladores de Java habrían adaptado su código para que se ajuste a los detalles de implementación: evite el acceso aleatorio, agregue un caché para acelerar el acceso o simplemente vuelva ArrayLista implementarlo por sí mismo, aunque sería incompatible con todos los demás códigos que realmente funcionan Listsolo. Eso sería terrible ... Pero ahora imagine que los maestros de Java realmente se dan cuenta de que una lista vinculada es terrible para la mayoría de los casos de uso reales, y decidieron cambiar a una lista de matriz para su únicoListclase disponible Esto afectaría el rendimiento de cada programa Java en el mundo, y la gente no estaría contenta con eso. Y el principal culpable es que los detalles de implementación estaban disponibles, y los desarrolladores asumieron que esos detalles son un contrato permanente en el que pueden confiar. Por eso es importante ocultar los detalles de implementación y solo definir un contrato abstracto. Este es el propósito de una interfaz: definir qué tipo de entrada acepta un método y qué tipo de salida se espera, sin exponer todas las agallas que tentarían a los programadores a ajustar su código para que se ajuste a los detalles internos que podrían cambiar con cualquier actualización futura. .

Una clase abstracta está en el medio entre las interfaces y las clases concretas. Se supone que ayuda a las implementaciones a compartir código común o aburrido. Por ejemplo, AbstractCollectionproporciona implementaciones básicas isEmptybasadas en el tamaño es 0, containscomo iterar y comparar, addAllcomo repetido add, y así sucesivamente. Esto permite que las implementaciones se centren en las partes cruciales que las diferencian: cómo almacenar y recuperar datos.

API versus SPI

Las interfaces son puertas de enlace de baja cohesión entre diferentes partes del código. Permiten que las bibliotecas existan y evolucionen sin interrumpir a cada usuario de la biblioteca cuando algo cambia internamente. Se llama interfaz de programación de aplicaciones , no clases de programación de aplicaciones. En una escala más pequeña, también permiten que múltiples desarrolladores colaboren con éxito en proyectos a gran escala, separando diferentes módulos a través de interfaces bien documentadas.

Las clases abstractas son auxiliares de alta cohesión que se utilizarán al implementar una interfaz, asumiendo cierto nivel de detalles de implementación. Alternativamente, las clases abstractas se utilizan para definir SPI, interfaces de proveedor de servicios.

La diferencia entre una API y un SPI es sutil, pero importante: para una API, el foco está en quién lo usa , y para un SPI el foco está en quién lo implementa .

Agregar métodos a una API es fácil, todos los usuarios existentes de la API seguirán compilando. Agregar métodos a un SPI es difícil, ya que cada proveedor de servicios (implementación concreta) tendrá que implementar los nuevos métodos. Si se utilizan interfaces para definir un SPI, un proveedor tendrá que lanzar una nueva versión cada vez que cambie el contrato de SPI. Si se usan clases abstractas en su lugar, los nuevos métodos podrían definirse en términos de métodos abstractos existentes, o como throw not implemented exceptionresguardos vacíos , lo que al menos permitirá que una versión anterior de una implementación de servicio aún se compile y ejecute.

Una nota sobre Java 8 y los métodos predeterminados

Aunque Java 8 introdujo métodos predeterminados para las interfaces, lo que hace que la línea entre las interfaces y las clases abstractas sea aún más borrosa, esto no fue para que las implementaciones puedan reutilizar el código, sino para que sea más fácil cambiar las interfaces que sirven como API y como SPI (o se usan incorrectamente para definir SPI en lugar de clases abstractas).

¿Cuál usar?

  1. ¿Se supone que la cosa debe ser utilizada públicamente por otras partes del código o por otro código externo? Agregue una interfaz para ocultar los detalles de implementación del contrato público abstracto, que es el comportamiento general de la cosa.
  2. Es la cosa algo que se supone que tiene múltiples implementaciones con una gran cantidad de código en común? Haga una interfaz y una implementación abstracta e incompleta.
  3. ¿Alguna vez habrá una sola implementación y nadie más la usará? Solo conviértalo en una clase concreta.
    1. "ever" es mucho tiempo, puedes jugar de forma segura y aun así agregar una interfaz encima.

Un corolario: a la inversa, a menudo se hace mal: al usar una cosa , siempre intente usar la clase / interfaz más genérica que realmente necesita. En otras palabras, no declare sus variables como ArrayList theList = new ArrayList(), a menos que realmente tenga una dependencia muy fuerte de que sea una lista de matriz , y ningún otro tipo de lista lo cortaría por usted. Utilice en su List theList = new ArrayListlugar, o incluso Collection theCollection = new ArrayListsi el hecho de que sea una lista, y no cualquier otro tipo de colección, en realidad no importa.

Sergiu Dumitriu
fuente
4

Realmente no es la respuesta a la pregunta original, pero una vez que tenga la respuesta a la diferencia entre ellos, ingresará el dilema cuándo usar cada uno: ¿ Cuándo usar interfaces o clases abstractas? ¿Cuándo usar ambos?

Tengo un conocimiento limitado de OOP, pero ver las interfaces como un equivalente de un adjetivo en gramática me ha funcionado hasta ahora (¡corríjame si este método es falso!). Por ejemplo, los nombres de interfaz son como atributos o capacidades que puede dar a una clase, y una clase puede tener muchos de ellos: ISerializable, ICountable, IList, ICacheable, IHappy, ...

azkotoki
fuente
3

La herencia se usa para dos propósitos:

  • Para permitir que un objeto considere los miembros de datos de tipo primario y las implementaciones de métodos como propias.

  • Para permitir que una referencia a un objeto de un tipo sea utilizada por un código que espera una referencia al objeto de supertipo.

En los lenguajes / marcos que admiten la herencia múltiple generalizada, a menudo hay poca necesidad de clasificar un tipo como "interfaz" o "clase abstracta". Sin embargo, los lenguajes y marcos populares permitirán que un tipo considere los miembros de datos de otro tipo o las implementaciones de métodos como propias, aunque permiten que un tipo sea sustituible por un número arbitrario de otros tipos.

Las clases abstractas pueden tener miembros de datos e implementaciones de métodos, pero solo pueden ser heredadas por clases que no heredan de ninguna otra clase. Las interfaces casi no imponen restricciones a los tipos que las implementan, pero no pueden incluir miembros de datos o implementaciones de métodos.

Hay momentos en que es útil que los tipos sean sustituibles por muchas cosas diferentes; Hay otros momentos en que es útil para los objetos considerar los miembros de datos de tipo primario y las implementaciones de métodos como propias. Hacer una distinción entre interfaces y clases abstractas permite utilizar cada una de esas habilidades en los casos en que sea más relevante.

Super gato
fuente
3

Puntos clave:

  • La clase abstracta puede tener propiedades, campos de datos, métodos (completos / incompletos) ambos.
  • Si el método o las Propiedades se definen en una palabra clave abstracta que debe anular en la clase derivada (funciona como una funcionalidad estrechamente acoplada)
  • Si define una palabra clave abstracta para el método o las propiedades en la clase abstracta, no puede definir el cuerpo del método y obtener / establecer el valor para las propiedades y eso debe anularse en la clase derivada.
  • La clase abstracta no admite herencia múltiple.
  • La clase abstracta contiene constructores.
  • Una clase abstracta puede contener modificadores de acceso para los subs, funciones, propiedades.
  • Solo el miembro completo de la clase abstracta puede ser estático.
  • Una interfaz puede heredar de otra interfaz solamente y no puede heredar de una clase abstracta, mientras que una clase abstracta puede heredar de otra clase abstracta u otra interfaz.

Ventaja:

  • Es un tipo de contrato que obliga a todas las subclases a llevar a cabo las mismas jerarquías o estándares.
  • Si varias implementaciones son del mismo tipo y usan un comportamiento o estado común, entonces es mejor usar la clase abstracta.
  • Si agregamos un nuevo método a una clase abstracta, entonces tenemos la opción de proporcionar una implementación predeterminada y, por lo tanto, todo el código existente podría funcionar correctamente.
  • Permite una ejecución rápida que la interfaz (la interfaz requiere más tiempo para encontrar el método real en las clases correspondientes).
  • Se puede usar para un acoplamiento apretado y flojo.

encuentre detalles aquí ... http://pradeepatkari.wordpress.com/2014/11/20/interface-and-abstract-class-in-c-oops/

Pradeep atkari
fuente
3

La forma más corta de resumirlo es que an interfacees:

  1. Completamente abstracto, aparte de defaulty staticmétodos; Si bien tiene definiciones (firmas de métodos + implementaciones) defaulty staticmétodos, solo tiene declaraciones (firmas de métodos) para otros métodos.
  2. Sujeto a reglas más laxas que las clases (una clase puede implementar múltiples interfacesy una interfacepuede heredar de múltiples interfaces). Todas las variables son implícitamente constantes, especificadas como public static finalo no. Todos los miembros están implícitamente public, ya sea especificado como tal o no.
  3. Generalmente se usa como garantía de que la clase implementadora tendrá las características especificadas y / o será compatible con cualquier otra clase que implemente la misma interfaz.

Mientras tanto, una abstractclase es:

  1. En cualquier lugar, desde completamente abstracto hasta completamente implementado, con una tendencia a tener uno o más abstractmétodos. Puede contener declaraciones y definiciones, con declaraciones marcadas como abstract.
  2. Una clase completa, y sujeta a las reglas que gobiernan otras clases (solo puede heredar de una clase), con la condición de que no pueda ser instanciada (porque no hay garantía de que esté completamente implementada). Puede tener variables miembro no constantes. Puede implementar el control de acceso de los miembros, la restricción de los miembros como protected, private, o paquete privada (no especificado).
  3. Generalmente se usa para proporcionar la mayor parte de la implementación que pueden compartir múltiples subclases, o para proporcionar la mayor cantidad de implementación que el programador puede proporcionar.

O, si queremos hervir todo abajo a una sola frase: Una interfacees lo que la clase que implementa tiene , sino una abstractclase es lo que la subclase es .

Justin Time - Restablece a Monica
fuente
3

Me gustaría agregar una diferencia más que tiene sentido. Por ejemplo, tiene un marco con miles de líneas de código. Ahora, si desea agregar una nueva característica en todo el código usando un método enhaUI (), entonces es mejor agregar ese método en clase abstracta en lugar de en la interfaz. Porque, si agrega este método en una interfaz, debe implementarlo en toda la clase implementada, pero no es el caso si agrega el método en clase abstracta.

Sin dientes
fuente
3

Para dar una respuesta simple pero clara, ayuda a establecer el contexto: utiliza ambos cuando no desea proporcionar implementaciones completas.

La principal diferencia es que una interfaz no tiene ninguna implementación (solo métodos sin cuerpo), mientras que las clases abstractas pueden tener miembros y métodos con un cuerpo también, es decir, pueden implementarse parcialmente.

usuario3775501
fuente
Como lo respondió hace un momento, su respuesta no tiene en cuenta la defaultpalabra clave en Java 8 con la que también puede definir métodos concretos en las interfaces.
philantrovert
Como dije, esto estaba destinado a ser una "respuesta simple pero clara" para alguien en la etapa de aprender cuál es la diferencia. Para alguien así, no es beneficioso saber sobre ese tipo de excepción, solo sería muy confuso.
user3775501
3

Diferencias entre la clase abstracta y la interfaz en nombre de la implementación real.

Interfaz : es una palabra clave y se utiliza para definir la plantilla o el plano de un objeto y obliga a todas las subclases a seguir el mismo prototipo, ya que, como implementación, todas las subclases son libres de implementar la funcionalidad según Es requisito.

Algunos de los otros casos de uso donde deberíamos usar la interfaz.

Comunicación entre dos objetos externos (integración de terceros en nuestra aplicación) realizada a través de la interfaz aquí. La interfaz funciona como contrato.

Clase abstracta: Resumen, es una palabra clave y cuando usamos esta palabra clave antes de cualquier clase, se convierte en una clase abstracta. Se usa principalmente cuando necesitamos definir la plantilla, así como algunas funciones predeterminadas de un objeto que es seguido por todos los subclases y de esta manera elimina el código redundante y uno más casos de uso donde podemos usar la clase abstracta , como no queremos que otras clases puedan instanciar directamente un objeto de la clase, solo las clases derivadas pueden usar la funcionalidad.

Ejemplo de clase abstracta:

 public abstract class DesireCar
  {

 //It is an abstract method that defines the prototype.
     public abstract void Color();

  // It is a default implementation of a Wheel method as all the desire cars have the same no. of wheels.   
 // and hence no need to define this in all the sub classes in this way it saves the code duplicasy     

  public void Wheel() {          

               Console.WriteLine("Car has four wheel");
                }
           }


    **Here is the sub classes:**

     public class DesireCar1 : DesireCar
        {
            public override void Color()
            {
                Console.WriteLine("This is a red color Desire car");
            }
        }

        public class DesireCar2 : DesireCar
        {
            public override void Color()
            {
                Console.WriteLine("This is a red white Desire car");
            }
        }

Ejemplo de interfaz:

  public interface IShape
        {
          // Defines the prototype(template) 
            void Draw();
        }


  // All the sub classes follow the same template but implementation can be different.

    public class Circle : IShape
    {
        public void Draw()
        {
            Console.WriteLine("This is a Circle");
        }
    }

    public class Rectangle : IShape
    {
        public void Draw()
        {
            Console.WriteLine("This is a Rectangle");
        }
    }
Sheo Dayal Singh
fuente
3

Puede encontrar una clara diferencia entre la interfaz y la clase abstracta.

Interfaz

  • La interfaz solo contiene métodos abstractos.
  • Obligue a los usuarios a implementar todos los métodos cuando implemente la interfaz.
  • Contiene solo variables finales y estáticas.
  • Declarar usando la palabra clave de interfaz.
  • Todos los métodos de una interfaz deben definirse como públicos.
  • Una interfaz puede extenderse o una clase puede implementar varias otras interfaces.

Clase abstracta

  • La clase abstracta contiene métodos abstractos y no abstractos.

  • No obliga a los usuarios a implementar todos los métodos cuando heredan la clase abstracta.

  • Contiene todo tipo de variables, incluidas primitivas y no primitivas.

  • Declarar usando una palabra clave abstracta.

  • Los métodos y miembros de una clase abstracta se pueden definir con cualquier visibilidad.

  • Una clase secundaria solo puede extender una sola clase (abstracta u concreta).

Rahul Chauhan
fuente
2

Una clase abstracta es una clase cuyo objeto no se puede crear o una clase que no se puede instanciar. Un método abstracto hace que una clase sea abstracta. Una clase abstracta necesita ser heredada para anular los métodos que se declaran en la clase abstracta. No hay restricciones en los especificadores de acceso. Una clase abstracta puede tener constructores y otros métodos concretos (métodos no abstractos) en ellos, pero la interfaz no puede tenerlos.

Una interfaz es un modelo / plantilla de métodos (por ejemplo, se proporciona una casa en un papel (casa de interfaz) y diferentes arquitectos usarán sus ideas para construirla (las clases de arquitectos que implementan la interfaz de la casa). Es una colección de métodos abstractos, métodos predeterminados, métodos estáticos, variables finales y clases anidadas. Todos los miembros serán finales o públicos, no se permiten especificadores de acceso protegidos y privados. No se permite la creación de objetos. Se debe hacer una clase para utilizar el implementando la interfaz y también para anular el método abstracto declarado en la interfaz. Una interfaz es un buen ejemplo de acoplamiento flojo (polimorfismo dinámico / enlace dinámico) Una interfaz implementa el polimorfismo y la abstracción. Indica qué hacer, pero cómo hacerlo está definido por el implementando clase. Por ejemplo.es una compañía automotriz y quiere que algunas características sean las mismas para todo el automóvil que está fabricando, de modo que la compañía esté haciendo un vehículo de interfaz que tendrá esas características y diferentes clases de automóviles (como Maruti Suzkhi, Maruti 800) anularán esas características (funciones).

¿Por qué interfaz cuando ya tenemos clase abstracta? Java solo admite herencia multinivel y jerárquica, pero con la ayuda de la interfaz podemos implementar herencia múltiple.

Tutu Kumari
fuente
2

En términos prácticos (JAVA), la principal diferencia entre la clase abstracta y la interfaz es que la clase abstracta puede mantener el estado. Además del estado de espera, también podemos lograr operaciones de descanso con la interfaz.

Tokala Sai Teja
fuente
1

En una interfaz, todos los métodos deben ser solo definiciones, no se debe implementar una sola.

Pero en una clase abstracta debe haber un método abstracto con solo definición, pero otros métodos también pueden estar en la clase abstracta con implementación ...

Shamim Ahmed
fuente
1

Tenemos varias diferencias estructurales / sintácticas entre la interfaz y la clase abstracta. Algunas diferencias más son

[1] Diferencia basada en escenarios :

Las clases abstractas se utilizan en escenarios en los que queremos restringir al usuario para que cree un objeto de la clase principal Y creemos que se agregarán métodos más abstractos en el futuro.

La interfaz se debe usar cuando estamos seguros de que no puede haber más métodos abstractos para proporcionar. Entonces solo se publica una interfaz.

[2] Diferencia conceptual :

"¿Necesitamos proporcionar métodos más abstractos en el futuro" si SÍ lo hace clase abstracta y si NO lo hace Interfaz.

(Más apropiado y válido hasta java 1.7)

Shashank Bodkhe
fuente
1

Generalmente, la clase abstracta se usa para el núcleo de algo, pero la interfaz se usa para agregar periféricos.

cuando desee crear un tipo base para el vehículo, debe usar la clase abstracta, pero si desea agregar alguna funcionalidad o propiedad que no sea parte del concepto base del vehículo, debe usar la interfaz, por ejemplo, desea agregar la función "ToJSON ()" .

La interfaz tiene un amplio rango de abstracción en lugar de una clase abstracta. puedes ver esto al pasar argumentos. Mira este ejemplo:

ingrese la descripción de la imagen aquí

si usa un vehículo como argumento, puede usar uno de sus tipos derivados (autobús o auto, la misma categoría, solo categoría de vehículo). pero cuando usa la interfaz IMoveable como argumento, tiene más opciones.

MRMF
fuente