poo interfaces clases clase and abstractas abstracta oop interface abstract-class

oop - interfaces - interface vs abstract class java



Interfaz vs clase abstracta(OO general) (30)

  1. Interfaz:
    • No implementamos (o definimos) métodos, lo hacemos en clases derivadas.
    • No declaramos variables miembro en interfaces.
    • Las interfaces expresan la relación HAS-A. Eso significa que son una máscara de objetos.
  2. Clase abstracta:
    • Podemos declarar y definir métodos en clase abstracta.
    • Ocultamos a los constructores de la misma. Eso significa que no hay ningún objeto creado a partir de él directamente.
    • La clase abstracta puede contener variables miembro.
    • Las clases derivadas heredan a la clase abstracta que significa que los objetos de las clases derivadas no están enmascarados, sino que heredan la clase abstracta La relación en este caso es IS-A.

Esta es mi opinión.

Recientemente he tenido dos entrevistas telefónicas en las que me han preguntado sobre las diferencias entre una interfaz y una clase abstracta. He explicado todos los aspectos de ellos que se me ocurren, pero parece que están esperando que mencione algo específico, y no sé qué es.

Desde mi experiencia creo que lo siguiente es cierto. Si me falta un punto importante, por favor hágamelo saber.

Interfaz:

Cada método declarado en una interfaz deberá implementarse en la subclase. Solo eventos, delegados, propiedades (C #) y métodos pueden existir en una interfaz. Una clase puede implementar múltiples interfaces.

Clase abstracta:

Solo los métodos abstractos deben ser implementados por la subclase. Una clase abstracta puede tener métodos normales con implementaciones. La clase abstracta también puede tener variables de clase al lado de Eventos, Delegados, Propiedades y Métodos. Una clase solo puede implementar una clase abstracta solo debido a la no existencia de herencia múltiple en C #.

  1. Después de todo eso, al entrevistador se le ocurrió la pregunta "¿Qué pasaría si tuviera una clase de resumen con solo métodos abstractos? ¿Cómo sería diferente de una interfaz? No sabía la respuesta, pero creo que es la herencia como se mencionó anteriormente, ¿verdad?

  2. Otro entrevistador me preguntó qué pasaría si tuviera una variable pública dentro de la interfaz, ¿en qué se diferenciaría de la clase abstracta? Insistí en que no puedes tener una variable pública dentro de una interfaz. No sabía lo que quería escuchar, pero tampoco estaba satisfecho.

Ver también :


Al implementar interfaces, está logrando la composición (relaciones "has-a") en lugar de la herencia (relaciones "is-a"). Ese es un principio importante para recordar cuando se trata de cosas como los patrones de diseño en los que necesita usar interfaces para lograr una composición de comportamientos en lugar de una herencia.


Conceptualmente hablando, manteniendo la implementación específica del idioma, las reglas, los beneficios y el logro de cualquier objetivo de programación mediante el uso de cualquiera o ambos, puede o no puede tener un código / datos / propiedad, bla, bla, herencia única o múltiple, todo a un lado

1- Resumen (o extracto puro) La clase está destinada a implementar la jerarquía. Si los objetos de su negocio tienen un aspecto estructuralmente similar, solo representan una clase de relación padre-hijo (jerarquía) y luego se utilizarán las clases de herencia / resumen. Si su modelo de negocio no tiene una jerarquía, entonces no debe utilizarse la herencia (aquí no estoy hablando de programación lógica, por ejemplo, algunos patrones de diseño requieren herencia). Conceptualmente, la clase abstracta es un método para implementar la jerarquía de un modelo de negocio en OOP, no tiene nada que ver con las Interfaces; en realidad, la comparación de la clase Abstracta con la Interfaz no tiene sentido porque ambas son cosas conceptualmente diferentes, se pregunta en las entrevistas para verificar el Los conceptos, ya que parecen tener una funcionalidad algo similar cuando se trata de la implementación, y los programadores usualmente hacemos más hincapié en la codificación. [Tenga en cuenta esto también que la abstracción es diferente a la clase abstracta].

2- una interfaz es un contrato, una funcionalidad empresarial completa representada por una o más funciones. Es por eso que se implementa y no se hereda. Un objeto de negocio (parte o no de una jerarquía) puede tener cualquier número de funcionalidad empresarial completa. No tiene nada que ver con clases abstractas significa herencia en general. Por ejemplo, un humano puede EJECUTARSE, un elefante puede EJECUTARSE, un pájaro puede EJECUTARSE, y así sucesivamente, todos estos objetos de diferente jerarquía implementarán la interfaz EJECUTARSE o la interfaz EAT o SPEAK. No entre en la implementación, ya que podría implementarla como si tuviera clases abstractas para cada tipo que implementa estas interfaces. Un objeto de cualquier jerarquía puede tener una funcionalidad (interfaz) que no tiene nada que ver con su jerarquía.

Creo que las Interfaces no se inventaron para lograr múltiples herencias o para exponer el comportamiento público, y de manera similar, las clases abstractas puras no deben invalidar las interfaces, pero la Interfaz es una funcionalidad que un objeto puede hacer (a través de las funciones de esa interfaz) y la Clase Abstracta representa una padre de una jerarquía para producir hijos con la estructura central (propiedad + funcionalidad) del padre

Cuando se le pregunta sobre la diferencia, en realidad es una diferencia conceptual, no la diferencia en la implementación específica del idioma, a menos que se le pida explícitamente.

Creo que ambos entrevistadores esperaban una línea clara de diferencia entre estos dos y cuando fallas intentaron conducirte hacia esta diferencia implementando UNO como el OTRO

¿Qué pasaría si tuvieras una clase abstracta con solo métodos abstractos?


Corto: las clases abstractas se utilizan para modelar una jerarquía de clases de clases de aspecto similar (por ejemplo, Animal puede ser una clase abstracta y Human, Lion, Tiger pueden ser clases derivadas concretas)

Y

La interfaz se utiliza para la comunicación entre 2 clases similares / no similares a las que no le importa el tipo de clase que implementa la interfaz (por ejemplo, Height puede ser propiedad de la interfaz y puede ser implementado por Human, Building, Tree. No importa si puede comer , puedes nadar, puedes morir o cualquier cosa ... solo importa una cosa que necesitas para tener Altura (implementación en tu clase)).


Creo que la respuesta que buscan es la diferencia fundamental o OPPS filosófica.

La herencia de la clase abstracta se usa cuando la clase derivada comparte las propiedades y el comportamiento de la clase abstracta. El tipo de comportamiento que realmente define la clase.

Por otro lado, la herencia de interfaz se utiliza cuando las clases comparten un comportamiento periférico, que no necesariamente definen la clase derivada.

Por ejemplo. Un Coche y un Camión comparten muchas de las propiedades y comportamientos centrales de una clase abstracta de Automóviles, pero también comparten algunos comportamientos periféricos como Generar escape que incluso clases no automovilísticas como Drillers o PowerGenerators comparten y no necesariamente define un Coche o un Camión. , así que Car, Truck, Driller y PowerGenerator pueden compartir la misma interfaz IExhaust.


Creo que no les gustó su respuesta porque dio las diferencias técnicas en lugar de las de diseño. La pregunta es como una pregunta troll para mí. De hecho, las interfaces y las clases abstractas tienen una naturaleza completamente diferente, por lo que realmente no se pueden comparar. Le daré mi visión de cuál es el rol de una interfaz y cuál es el rol de una clase abstracta.

Interfaz: se utiliza para garantizar un contrato y hacer un bajo acoplamiento entre clases para tener una aplicación más mantenible, escalable y comprobable.

clase abstracta: solo se utiliza para factorizar algunos códigos entre clases de la misma responsabilidad. Tenga en cuenta que esta es la razón principal por la que la herencia múltiple es algo malo en OOP, porque una clase no debe manejar muchas responsabilidades (en su lugar, use la composition ).

Por lo tanto, las interfaces tienen una función arquitectónica real, mientras que las clases abstractas son casi solo un detalle de la implementación (si se usa correctamente, por supuesto).


Explicaré los detalles de profundidad de la interfaz y la clase abstracta. Si conoce el panorama general de la interfaz y la clase abstracta, entonces la primera pregunta le llegará a la mente cuando deberíamos usar la interfaz y cuándo deberíamos usar la clase abstracta. Así que por favor verifique la explicación de la clase Interfaz y Resumen a continuación

  1. ¿Cuándo deberíamos usar Interface?

    Si no conoce la implementación, solo tenemos la especificación de requisitos, entonces vamos con Interfaz.

  2. ¿Cuándo deberíamos usar Abstract Class?

    Si conoce la implementación pero no completamente (implementación parcial), entonces vamos con la clase Abstract.

    Interfaz

    Cada método por defecto, la interfaz pública de medios abstractos es 100% pura abstracta.

    Resumen

    puede tener Método concreto y Método abstracto, qué es el Método concreto, que tiene implementación en la clase Resumen. Una clase abstracta es una clase que se declara abstracta; puede incluir o no métodos abstractos.

    Interfaz

    No podemos declarar interfaz como privada, protegida.

    P. ¿Por qué no estamos declarando a la Interfaz como privada y protegida?

    Porque, por defecto, el método de la interfaz es un resumen público, por lo que no estamos declarando la interfaz como privada y protegida.

    Método de interfaz
    tampoco podemos declarar la interfaz como privada, protegida, final, estática, sincronizada, nativa ...

    Daré la razón: por qué no estamos declarando el método sincronizado porque no podemos crear el objeto de la interfaz y la sincronización está funcionando en el objeto y no está declarando el método sincronizado. El concepto transitorio tampoco es aplicable porque el trabajo transitorio con la sincronización.

    Resumen

    Estamos contentos de usar con estática pública final privada ... significa que no hay restricciones aplicables en abstracto.

    Interfaz

    Las variables se declaran en la Interfaz como una final estática pública predeterminada, por lo que tampoco somos variables declaradas como privadas, protegidas.

    El modificador volátil tampoco es aplicable en la interfaz porque la variable de la interfaz es, por defecto, la variable final y estática pública predeterminada, no puede cambiar el valor una vez que asigna el valor en variable y una vez que haya declarado la variable en la interfaz, debe asignar la variable.

    Y la variable volátil es mantener los cambios por lo que es opp. Para finalizar es por eso que no utilizamos variable volátil en la interfaz.

    Resumen

    Variable abstracta sin necesidad de declarar final estática pública.

Espero que este artículo sea de utilidad.


Hay un par de otras diferencias -

Las interfaces no pueden tener implementaciones concretas. Las clases base abstractas pueden. Esto le permite proporcionar implementaciones concretas allí. Esto puede permitir que una clase base abstracta proporcione un contrato más riguroso, ya que una interfaz realmente solo describe cómo se utiliza una clase. (La clase base abstracta puede tener miembros no virtuales que definen el comportamiento, lo que le da más control al autor de la clase base).

Más de una interfaz se puede implementar en una clase. Una clase solo puede derivar de una única clase base abstracta. Esto permite la jerarquía polimórfica utilizando interfaces, pero no clases base abstractas. Esto también permite una pseudo-multi-herencia utilizando interfaces.

Las clases base abstractas se pueden modificar en v2 + sin romper la API. Los cambios en las interfaces están rompiendo cambios.

[C # / .NET Específico] Las interfaces, a diferencia de las clases base abstractas, pueden aplicarse a tipos de valor (estructuras). Las estructuras no pueden heredar de las clases base abstractas. Esto permite que los contratos de comportamiento / pautas de uso se apliquen en los tipos de valor.


Los entrevistadores están ladrando un árbol extraño. Para lenguajes como C # y Java, hay una diferencia, pero en otros lenguajes como C ++ no lo hay. La teoría OO no diferencia los dos, simplemente la sintaxis del lenguaje.

Una clase abstracta es una clase con implementación e interfaz (métodos virtuales puros) que se heredarán. Las interfaces en general no tienen ninguna implementación, sino solo funciones virtuales puras.

En C # o Java, una clase abstracta sin ninguna implementación difiere de una interfaz solo en la sintaxis utilizada para heredar de ella y en el hecho de que solo puede heredar de una.


Para .Net,

Su respuesta al segundo entrevistador también es la respuesta al primero ... Las clases abstractas pueden tener implementación, Y el estado, las interfaces no pueden ...

EDITAR: En otra nota, ni siquiera usaría la frase ''subclase'' (o la frase ''herencia'') para describir las clases que están ''definidas para implementar'' una interfaz. Para mí, una interfaz es una definición de un contrato que una clase debe cumplir si se ha definido para "implementar" esa interfaz. No hereda nada ... Tienes que agregar todo tú mismo, explícitamente.


Qué tal una analogía: cuando estaba en la Fuerza Aérea, fui a entrenamiento de piloto y me convertí en piloto de la Fuerza Aérea de los EE. UU. En ese momento no estaba calificado para volar nada, y tuve que asistir a un entrenamiento de tipo avión. Una vez que califiqué, fui piloto (clase abstracta) y piloto C-141 (clase concreta). En una de mis tareas, me dieron un deber adicional: Oficial de seguridad. Ahora todavía era piloto y piloto C-141, pero también desempeñé funciones de Oficial de seguridad (implementé ISafetyOfficer, por así decirlo). No se requería que un piloto fuera un oficial de seguridad, otras personas podrían haberlo hecho también.

Todos los pilotos de la USAF tienen que seguir ciertas regulaciones de la Fuerza Aérea, y todos los pilotos C-141 (o F-16, o T-38) son pilotos de la USAF. Cualquiera puede ser un oficial de seguridad. Entonces, para resumir:

  • Piloto: clase abstracta.
  • C-141 Piloto: clase concreta
  • Oficial de seguridad: interfaz

nota agregada: esto fue pensado como una analogía para ayudar a explicar el concepto, no una recomendación de codificación. Ver los diversos comentarios a continuación, la discusión es interesante.


Si bien su pregunta indica que es para "OO general", realmente parece estar enfocándose en el uso de estos términos en .NET.

En .NET (similar para Java):

  • Las interfaces no pueden tener estado o implementación
  • una clase que implementa una interfaz debe proporcionar una implementación de todos los métodos de esa interfaz
  • las clases abstractas pueden contener estado (miembros de datos) y / o implementación (métodos)
  • las clases abstractas pueden heredarse sin implementar los métodos abstractos (aunque tal clase derivada es abstracta en sí misma)
  • las interfaces pueden ser de herencia múltiple, las clases abstractas pueden no serlo (esta es probablemente la razón concreta clave para que las interfaces existan por separado de las clases de extracción), permiten una implementación de herencia múltiple que elimina muchos de los problemas del IM general.

Como términos generales de OO, las diferencias no están necesariamente bien definidas. Por ejemplo, hay programadores de C ++ que pueden tener definiciones rígidas similares (las interfaces son un subconjunto estricto de clases abstractas que no pueden contener la implementación), mientras que algunos pueden decir que una clase abstracta con algunas implementaciones predeterminadas sigue siendo una interfaz o que una no abstracta. clase todavía puede definir una interfaz.

De hecho, hay un modismo en C ++ llamado Interfaz no virtual (NVI) donde los métodos públicos son métodos no virtuales que "combinan" con los métodos virtuales privados:


Si considera que java es un lenguaje OOP para responder a esta pregunta, la versión de Java 8 hace que parte del contenido de las respuestas anteriores sea obsoleto. Ahora la interfaz java puede tener métodos predeterminados con implementación concreta.

El website Oracle proporciona diferencias clave entre la interface y abstract clase abstract .

Considere usar clases abstractas si:

  1. Desea compartir código entre varias clases estrechamente relacionadas.
  2. Usted espera que las clases que extiendan su clase abstracta tengan muchos métodos o campos comunes, o que 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. Usted espera que las clases no relacionadas implementen su interfaz. Por ejemplo, muchos objetos no relacionados pueden implementar una interfaz Serializable .
  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 de tipo múltiple.

En términos simples, me gustaría usar

Interfaz: para implementar un contrato por múltiples objetos no relacionados.

clase abstracta: para implementar el mismo o diferente comportamiento entre múltiples objetos relacionados

Eche un vistazo al ejemplo de código para entender las cosas de manera clara: ¿Cómo debería haber explicado la diferencia entre una interfaz y una clase abstracta?


Interfaz : debe utilizarse si desea implicar una regla sobre los componentes que pueden o no estar relacionados entre sí.

Pros:

  1. Permite herencia múltiple.
  2. Proporciona abstracción al no exponer qué tipo exacto de objeto se está utilizando en el contexto
  3. Brinda consistencia mediante una firma específica del contrato.

Contras:

  1. Se deben implementar todos los contratos definidos.
  2. No se pueden tener variables o delegados.
  3. Una vez definido no se puede cambiar sin romper todas las clases.

Clase abstracta : se debe utilizar donde desee tener algún comportamiento básico o predeterminado o implementación para componentes relacionados entre sí.

Pros:

  1. Más rápido que la interfaz
  2. Tiene flexibilidad en la implementación (puede implementarla total o parcialmente)
  3. Se puede cambiar fácilmente sin romper las clases derivadas.

Contras:

  1. No puede ser instanciado
  2. No admite herencia múltiple

Clase abstracta y diferencia de interfaz:

  1. La clase abstracta puede tener métodos abstractos y no abstractos y la interfaz puede tener solo métodos abstractos.
  2. La clase abstracta no admite herencia múltiple y la interfaz admite herencia múltiple.
  3. La clase abstracta puede tener variables finales, no finales, estáticas y no estáticas. La interfaz solo tiene variables estáticas y finales.
  4. La clase abstracta puede tener métodos estáticos, método principal y constructor. La interfaz no puede tener métodos estáticos, método principal o constructor.
  5. La clase abstracta puede proporcionar la implementación de la interfaz y la interfaz no puede proporcionar la implementación de la clase abstracta.
  6. La palabra clave abstracta se utiliza para declarar la clase abstracta y la palabra clave de la interfaz se utiliza para declarar la interfaz.
  7. La clase abstracta logra una abstracción parcial (0 a 100%) porque hay métodos no abstractos también en la clase abstracta, mientras que la interfaz logra una abstracción total (100%).

Herencia
Considera un coche y un autobús. Son dos vehículos diferentes. Pero aún así, comparten algunas propiedades comunes como tener una dirección, frenos, engranajes, motor, etc.
Así que con el concepto de herencia, esto se puede representar de la siguiente manera ...

public class Vehicle { private Driver driver; private Seat[] seatArray; //In java and most of the Object Oriented Programming(OOP) languages, square brackets are used to denote arrays(Collections). //You can define as many properties as you want here ... }

Ahora una bicicleta ...

public class Bicycle extends Vehicle { //You define properties which are unique to bicycles here ... private Pedal pedal; }

Y un coche

public class Car extends Vehicle { private Engine engine; private Door[] doors; }

Eso es todo sobre la herencia . Los usamos para clasificar objetos en formas de Base más simples y sus hijos como vimos anteriormente.

Clases abstractas

Las clases abstractas son objetos incompletos . Para entenderlo mejor, consideremos la analogía del vehículo una vez más.
Un vehículo puede ser conducido. ¿Derecha? Pero diferentes vehículos se conducen de diferentes maneras ... Por ejemplo, no puede conducir un automóvil igual que conduce una bicicleta.
Entonces, ¿cómo representar la función de conducción de un vehículo? Es más difícil verificar qué tipo de vehículo es y conducirlo con su propia función; tendría que cambiar la clase de Conductor una y otra vez al agregar un nuevo tipo de vehículo.
Aquí viene el papel de las clases y métodos abstractos. Puede definir el método de la unidad como abstracto para indicar que cada hijo heredado debe implementar esta función.
Así que si modifica la clase de vehículo ...

//......Code of Vehicle Class abstract public void drive(); //.....Code continues

La Bicicleta y el Coche también deben especificar cómo conducirlo. De lo contrario, el código no se compilará y se generará un error.
En resumen ... una clase abstracta es una clase parcialmente incompleta con algunas funciones incompletas, que los hijos herederos deben especificar las suyas.

Interfaces Las interfaces están totalmente incompletas. No tienen propiedades. Solo indican que los hijos herederos son capaces de hacer algo ...
Supongamos que tienes diferentes tipos de teléfonos móviles contigo. Cada uno de ellos tiene diferentes maneras de hacer diferentes funciones; Ej: llamar a una persona. El fabricante del teléfono especifica cómo hacerlo. Aquí, los teléfonos móviles pueden marcar un número, es decir, se puede marcar. Vamos a representar esto como una interfaz.

public interface Dialable { public void dial(Number n); }

Aquí el creador del Dialable define cómo marcar un número. Solo tienes que darle un número para marcar.

// Makers define how exactly dialable work inside. Dialable PHONE1 = new Dialable() { public void dial(Number n) { //Do the phone1''s own way to dial a number } } Dialable PHONE2 = new Dialable() { public void dial(Number n) { //Do the phone2''s own way to dial a number } } //Suppose there is a function written by someone else, which expects a Dialable ...... public static void main(String[] args) { Dialable myDialable = SomeLibrary.PHONE1; SomeOtherLibrary.doSomethingUsingADialable(myDialable); } .....

De este modo, utilizando interfaces en lugar de clases abstractas, el autor de la función que utiliza un Dialable no necesita preocuparse por sus propiedades. Ej: ¿Tiene una pantalla táctil o un teclado de marcación? ¿Es un teléfono fijo fijo o un teléfono móvil? Solo necesitas saber si es dialable; ¿Hereda (o implementa) la interfaz Dialable?

Y lo que es más importante , si algún día cambias el Dialable por otro diferente

...... public static void main(String[] args) { Dialable myDialable = SomeLibrary.PHONE2; // <-- changed from PHONE1 to PHONE2 SomeOtherLibrary.doSomethingUsingADialable(myDialable); } .....

Puede estar seguro de que el código todavía funciona perfectamente porque la función que utiliza el dialable no depende (y no puede) de los detalles que no sean los especificados en la interfaz de Dialable. Ambos implementan una interfaz Dialable y eso es lo único que le importa a la función.

Los desarrolladores utilizan comúnmente las interfaces para garantizar la interoperabilidad (uso indistintamente) entre objetos, en la medida en que comparten una función común (al igual que usted puede cambiar a un teléfono fijo o móvil, en la medida en que solo necesita marcar un número). En resumen, las interfaces son una versión mucho más simple de las clases abstractas, sin ninguna propiedad.
Además, tenga en cuenta que puede implementar (heredar) tantas interfaces como desee, pero solo puede extender (heredar) una única clase padre.

Más información Clases abstractas vs Interfaces


Tipos de interfaz vs. clases base abstractas

Adaptado del libro Pro C # 5.0 y .NET 4.5 Framework .

El tipo de interfaz puede parecer muy similar a una clase base abstracta. Recuerde que cuando una clase está marcada como abstracta, puede definir cualquier número de miembros abstractos para proporcionar una interfaz polimórfica a todos los tipos derivados. Sin embargo, incluso cuando una clase define un conjunto de miembros abstractos, también es libre de definir cualquier número de constructores, datos de campo, miembros no abstractos (con implementación), etc. Las interfaces, por otro lado, contienen solo definiciones de miembros abstractos. La interfaz polimórfica establecida por una clase padre abstracta adolece de una limitación importante en cuanto a que solo los tipos derivados admiten los miembros definidos por el padre abstracto. Sin embargo, en sistemas de software más grandes, es muy común desarrollar múltiples jerarquías de clases que no tienen un padre común más allá de System.Object.Dado que los miembros abstractos en una clase base abstracta se aplican solo a los tipos derivados, no tenemos forma de configurar tipos en diferentes jerarquías para soportar la misma interfaz polimórfica. A modo de ejemplo, suponga que ha definido la siguiente clase abstracta:

public abstract class CloneableType { // Only derived types can support this // "polymorphic interface." Classes in other // hierarchies have no access to this abstract // member. public abstract object Clone(); }

Dada esta definición, solo los miembros que extienden CloneableType pueden admitir el método Clone (). Si crea un nuevo conjunto de clases que no extienden esta clase base, no puede obtener esta interfaz polimórfica. Además, puede recordar que C # no admite la herencia múltiple para las clases. Por lo tanto, si desea crear un MiniVan que sea un Coche y un CloneableType, no podrá hacerlo:

// Nope! Multiple inheritance is not possible in C# // for classes. public class MiniVan : Car, CloneableType { }

Como se puede imaginar, los tipos de interfaz vienen al rescate. Una vez que se ha definido una interfaz, puede ser implementada por cualquier clase o estructura, en cualquier jerarquía, dentro de cualquier espacio de nombres o cualquier conjunto (escrito en cualquier lenguaje de programación .NET) Como puedes ver, las interfaces son altamente polimórficas. Considere la interfaz estándar .NET llamada ICloneable, definida en el espacio de nombres del sistema. Esta interfaz define un solo método llamado Clone ():

public interface ICloneable { object Clone(); }


Aunque esta pregunta es bastante antigua, me gustaría agregar otro punto a favor de las interfaces:

Las interfaces se pueden inyectar utilizando cualquier herramienta de inyección de dependencia en la que, como muy pocos, la inyección de clase abstracta es compatible


Copiado de CLR a través de C # por Jeffrey Richter ...

A menudo escucho la pregunta: "¿Debo diseñar un tipo de base o una interfaz?" La respuesta no siempre es clara.

Aquí hay algunas pautas que podrían ayudarte:

■■ Relación IS-A vs. CAN-DO Un tipo puede heredar solo una implementación. Si el tipo derivado no puede reclamar una relación IS-A con el tipo base, no use un tipo base; utilizar una interfaz. Las interfaces implican una relación CAN-DO. Si la funcionalidad CAN-DO parece pertenecer a varios tipos de objetos, use una interfaz. Por ejemplo, un tipo puede convertir instancias de sí mismo a otro tipo (IConvertible), un tipo puede serializar una instancia de sí mismo (ISerializable), etc. Tenga en cuenta que los tipos de valor deben derivarse de System.ValueType y, por lo tanto, no pueden derivarse de una clase base arbitraria. En este caso, debe utilizar una relación CAN-DO y definir una interfaz.

■■ Facilidad de uso Es generalmente más fácil para usted como desarrollador definir un nuevo tipo derivado de un tipo base que implementar todos los métodos de una interfaz. El tipo base puede proporcionar mucha funcionalidad, por lo que el tipo derivado probablemente necesite solo modificaciones relativamente pequeñas en su comportamiento. Si proporciona una interfaz, el nuevo tipo debe implementar todos los miembros.

■■ Implementación consistente No importa qué tan bien esté documentado un contrato de interfaz, es muy poco probable que todos implementen el contrato al 100 por ciento correctamente. De hecho, COM sufre este mismo problema, por lo que algunos objetos COM funcionan correctamente solo con Microsoft Word o con Windows Internet Explorer. Al proporcionar un tipo base con una buena implementación predeterminada, comienza a usar un tipo que funciona y está bien probado; A continuación, puede modificar las partes que necesitan modificación.

■■ Creación de versiones Si agrega un método al tipo base, el tipo derivado hereda el nuevo método, comienza con un tipo que funciona y el código fuente del usuario ni siquiera tiene que volver a compilarse. Agregar un nuevo miembro a una interfaz obliga al heredero de la interfaz a cambiar su código fuente y recompilarlo.


Desde la perspectiva de la codificación

Una interfaz puede reemplazar una clase abstracta si la clase abstracta solo tiene métodos abstractos. De lo contrario, cambiar la clase Abstract a interfaz significa que perderá la reutilización del código que proporciona la herencia.

Desde la perspectiva del diseño

Manténgalo como una clase abstracta si es una relación "Es una" y necesita un subconjunto o toda la funcionalidad. Manténgalo como interfaz si es una relación "debería hacer".

Decida lo que necesita: solo la aplicación de la política o la reutilización del código Y la política.


Diferencia entre la interfaz de Java y la clase abstracta

  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 implementa 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 privado, protegido, etc.

  4. La interfaz de Java se debe implementar utilizando palabras clave "implementos"; Una clase abstracta de Java debe extenderse usando la palabra clave "extiende".

  5. Una interfaz puede extender solo otra interfaz Java, una clase abstracta puede extender otra clase Java e implementar múltiples interfaces Java.

  6. Una clase de 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 requiere una dirección adicional.


1) Una interfaz puede verse como una clase abstracta pura, es lo mismo, pero a pesar de esto, no es lo mismo implementar una interfaz y heredarla de una clase abstracta. Cuando hereda de esta clase abstracta pura, está definiendo una jerarquía -> herencia, si implementa la interfaz que no es y puede implementar tantas interfaces como desee, pero solo puede heredar de una clase.

2) Puede definir una propiedad en una interfaz, por lo que la clase que implementa esa interfaz debe tener esa propiedad.

Por ejemplo:

public interface IVariable { string name {get; set;} }

La clase que implementa esa interfaz debe tener una propiedad como esa.


Como ya habrán conseguido los conocimientos teóricos de los expertos, no estoy pasando mucho en repetir palabras a todos aquellos que aquí, en lugar permítanme explicar con un ejemplo sencillo en el que podemos usar / no se puede utilizar Interfacey Abstract class.

Tenga en cuenta que está diseñando una aplicación para enumerar todas las características de Cars. En varios puntos necesita herencia en común, ya que algunas de las propiedades como DigitalFuelMeter, Aire Acondicionado, ajuste de Asiento, etc. son comunes para todos los autos. Del mismo modo, necesitamos herencia para algunas clases solo, ya que algunas de las propiedades como el Sistema de frenado (ABS, EBD) son aplicables solo para algunos autos.

La siguiente clase actúa como una clase base para todos los autos:

public class Cars { public string DigitalFuelMeter() { return "I have DigitalFuelMeter"; } public string AirCondition() { return "I have AC"; } public string SeatAdjust() { return "I can Adjust seat"; } }

Tenga en cuenta que tenemos una clase separada para cada coches.

public class Alto : Cars { // Have all the features of Car class } public class Verna : Cars { // Have all the features of Car class + Car need to inherit ABS as the Braking technology feature which is not in Cars } public class Cruze : Cars { // Have all the features of Car class + Car need to inherit EBD as the Braking technology feature which is not in Cars }

Considere que necesitamos un método para heredar la tecnología de frenado para los autos Verna y Cruze (no aplicable para Alto). Aunque ambos usan tecnología de frenado, la "tecnología" es diferente. Así que estamos creando una clase abstracta en la que el método se declarará como abstracto y se debe implementar en sus clases secundarias.

public abstract class Brake { public abstract string GetBrakeTechnology(); }

Ahora estamos tratando de heredar de esta clase abstracta y el tipo de sistema de frenos se implementa en Verna y Cruze:

public class Verna : Cars,Brake { public override string GetBrakeTechnology() { return "I use ABS system for braking"; } } public class Cruze : Cars,Brake { public override string GetBrakeTechnology() { return "I use EBD system for braking"; } }

¿Ves el problema en las dos clases anteriores? Heredan de varias clases que C # .Net no permite incluso si el método se implementa en los hijos. Aquí viene la necesidad de la interfaz.

interface IBrakeTechnology { string GetBrakeTechnology(); }

Y la implementación se da a continuación:

public class Verna : Cars, IBrakeTechnology { public string GetBrakeTechnology() { return "I use ABS system for braking"; } } public class Cruze : Cars, IBrakeTechnology { public string GetBrakeTechnology() { return "I use EBD system for braking"; } }

Ahora, Verna y Cruze pueden lograr múltiples herencias con su propio tipo de tecnologías de frenado con la ayuda de Interface.


De otra respuesta mía , que trata principalmente de cuándo usar una frente a la otra:

En mi experiencia, las interfaces se utilizan mejor cuando tiene varias clases, cada una de las cuales debe responder al mismo método o métodos para que puedan usarse indistintamente por otro código que se escribirá contra la interfaz común de esas clases. El mejor uso de una interfaz es cuando el protocolo es importante pero la lógica subyacente puede ser diferente para cada clase. Si de lo contrario estaría duplicando la lógica, considere las clases abstractas o la herencia de clases estándar en su lugar.


La mayoría de las respuestas se centran en la diferencia técnica entre clase abstracta e interfaz, pero como técnicamente, una interfaz es básicamente un tipo de clase abstracta (una sin datos o implementación), creo que la diferencia conceptual es mucho más interesante, y eso podría ser lo Los entrevistadores están detrás.

Una interfaz es un acuerdo . Especifica: "Así es como vamos a hablar unos con otros". No puede tener ninguna implementación porque se supone que no tiene ninguna implementación. Es un contrato. Es como los .harchivos de cabecera en C.

Una clase abstracta es una implementación incompleta . Una clase puede o no implementar una interfaz, y una clase abstracta no tiene que implementarla completamente. Una clase abstracta sin ninguna implementación es inútil, pero totalmente legal.

Básicamente, cualquier clase, abstracta o no, trata sobre lo que es , mientras que una interfaz trata sobre cómo se usa . Por ejemplo: Animalpodría ser una clase abstracta que implemente algunas funciones metabólicas básicas, y que especifique métodos abstractos para la respiración y la locomoción sin dar una implementación, porque no tiene idea si debe respirar a través de las agallas o los pulmones, y si vuela, nada, camina o se arrastra Mount, por otro lado, podría ser una Interfaz, que especifica que puedes montar al animal, sin saber qué tipo de animal es (¡o si es un animal!).

El hecho de que detrás de escena, una interfaz es básicamente una clase abstracta con solo métodos abstractos, no importa. Conceptualmente, cumplen roles totalmente diferentes.


Las interfaces son una forma ligera de imponer un comportamiento particular. Esa es una forma de pensar.


Por supuesto, es importante comprender el comportamiento de la interfaz y la clase abstracta en OOP (y cómo los idiomas los manejan), pero creo que también es importante entender qué significa exactamente cada término. ¿Te imaginas que el ifcomando no funcione exactamente como el significado del término? Además, en realidad algunos idiomas están reduciendo, aún más, las diferencias entre una interfaz y un resumen ... si por casualidad algún día los dos términos operan de manera casi idéntica, al menos puede definirse dónde (y por qué) si alguno de ellos debería usado para.

Si lees algunos diccionarios y otras fuentes, puedes encontrar significados diferentes para el mismo término pero con algunas definiciones comunes. Creo que estos dos significados que encontré en este sitio son realmente buenos y adecuados.

Interfaz:

Una cosa o circunstancia que permite que elementos separados ya veces incompatibles se coordinen de manera efectiva.

Resumen:

Algo que concentra en sí mismo las cualidades esenciales de algo más extenso o más general, o de varias cosas; esencia.

Ejemplo:

Usted compró un auto y necesita combustible.

El modelo de su automóvil es XYZ, que es de género ABC, por lo que es un automóvil concreto, una instancia específica de un automóvil. Un coche no es un objeto real. De hecho, es un conjunto abstracto de estándares (cualidades) para crear un objeto específico. En resumen, Car es una clase abstracta , es "algo que concentra en sí mismo las cualidades esenciales de cualquier cosa más extensa o más general" .

El único combustible que coincida con las especificaciones del manual del automóvil debe usarse para llenar el tanque del automóvil. En realidad, no hay nada que lo limite a poner combustible, pero el motor funcionará correctamente solo con el combustible especificado, por lo que es mejor cumplir con sus requisitos. Los requisitos dicen que acepta, como otros autos del mismo género ABC, un conjunto estándar de combustible.

En una vista orientada a objetos, el combustible para el género ABCno debe declararse como una clase porque no hay combustible concreto para un género específico de automóvil. Si bien su automóvil podría aceptar un combustible de clase abstracta o combustible vehicular, debe recordar que solo un poco del combustible vehicular existente cumple con las especificaciones, aquellos que implementan los requisitos en el manual de su automóvil. En resumen, deberían implementar la interfaz ABCGenreFuel , que "... permite que los elementos separados ya veces incompatibles se coordinen de manera efectiva" .

Apéndice

Además, creo que debes tener en cuenta el significado del término clase, que es (del mismo sitio mencionado anteriormente):

Clase:

Un número de personas o cosas que se considera que forman un grupo debido a atributos, características, cualidades o rasgos comunes; tipo;

De esta manera, una clase (o clase abstracta) no debe representar solo atributos comunes (como una interfaz), sino algún tipo de grupo con atributos comunes. Una interfaz no necesita representar un tipo. Debe representar atributos comunes. De esta manera, creo que las clases y las clases abstractas pueden usarse para representar cosas que no deberían cambiar sus aspectos a menudo, como un ser humano, un mamífero, porque representa algunos tipos. Las clases no deberían cambiarse tan a menudo.


Responda a la segunda pregunta: la publicvariable definida en interfacees static finalpor defecto mientras que la publicvariable en abstractclase es una variable de instancia.


Una interfaz define un contrato para un servicio o conjunto de servicios. Proporcionan polimorfismo de manera horizontal, ya que dos clases completamente no relacionadas pueden implementar la misma interfaz pero se pueden usar indistintamente como un parámetro del tipo de interfaz que implementan, ya que ambas clases han prometido satisfacer el conjunto de servicios definidos por la interfaz. Las interfaces no proporcionan detalles de implementación.

Una clase abstracta define una estructura base para sus sub-cadenas y, opcionalmente, implementación parcial. Las clases abstractas proporcionan polimorfismo de manera vertical, pero direccional, en el sentido de que cualquier clase que hereda la clase abstracta puede tratarse como una instancia de esa clase abstracta pero no al revés. Las clases abstractas pueden y, a menudo, contienen detalles de implementación, pero no pueden ser instanciadas por sí mismas, solo sus subclases pueden ser "nuevas".

C # también permite la herencia de la interfaz, fíjate.


After all that, the interviewer came up with the question "What if you had an Abstract class with only abstract methods? How would that be different from an interface?"

docs.oracle.com/javase/tutorial/java/IandI/abstract.html dicen claramente que si una clase abstracta solo contiene declaraciones de métodos abstractos, debe declararse como una interfaz.

An another interviewer asked me what if you had a Public variable inside the interface, how would that be different than in Abstract Class?

Las variables en las interfaces son, por defecto, public static y final. La pregunta podría encuadrarse como: ¿qué sucede si todas las variables de la clase abstracta son públicas? Bueno, todavía pueden ser no estáticos y no finales a diferencia de las variables en las interfaces.

Finalmente, agregaría un punto más a los mencionados anteriormente: las clases abstractas son todavía clases y caen en un solo árbol de herencia mientras que las interfaces pueden estar presentes en la herencia múltiple