¿Cuándo debo usar interfaces en lugar de clases abstractas?

Me preguntaba cuándo debería usar interfaces.

Pensemos en lo siguiente:

public abstract class Vehicle { abstract float getSpeed(); } 

y:

 public interface IVehicle { float getSpeed(); } 

Puedo implementarlos fácilmente a ambos, tienen la misma funcionalidad … PERO también puedo agregar algunas variables a mi clase de vehículo, que probablemente deberían usarse en un vehículo (maxSpeed, carType …)

¿Cuál es la razón para usar interfaces?

¡Gracias!

EDITAR: Encontré un buen enlace al respecto en otro hilo: http://www.thecoldsun.com/en/content/01-2009/abstract-classes-and-interfaces

Desde Java Cómo progtwigr sobre clases abstractas:

Debido a que se usan solo como superclases en las jerarquías de herencia, nos referimos a ellas como superclases abstractas. Estas clases no se pueden usar para instanciar objetos, porque las clases abstractas están incompletas. Las subclases deben declarar las “piezas faltantes” para que se conviertan en clases “concretas”, desde las cuales se pueden crear instancias de objetos. De lo contrario, estas subclases también serán abstractas.

Para responder a su pregunta “¿Cuál es el motivo para usar interfaces?”:

El objective de una clase abstracta es proporcionar una superclase apropiada a partir de la cual otras clases puedan heredar y compartir un diseño común.

A diferencia de una interfaz:

Una interfaz describe un conjunto de métodos que pueden invocarse sobre un objeto, pero no proporciona implementaciones concretas para todos los métodos … Una vez que una clase implementa una interfaz, todos los objetos de esa clase tienen una relación is-a con el tipo de interfaz , y se garantiza que todos los objetos de la clase proporcionan la funcionalidad descrita por la interfaz. Esto también se aplica a todas las subclases de esa clase.

Entonces, para responder a su pregunta “Me preguntaba cuándo debería usar las interfaces”, creo que debería usar interfaces cuando desee una implementación completa y usar clases abstractas cuando desee piezas parciales para su diseño (para reutilización)

¿Cuál debería usar, clases abstractas o interfaces?

Considere usar clases abstractas si alguna de estas afirmaciones se aplica a su situación:

Desea compartir el código entre varias clases estrechamente relacionadas.

Espera que las clases que amplían 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).

Desea declarar campos no estáticos o no finales. Esto le permite definir métodos que pueden acceder y modificar el estado del objeto al que pertenecen.

Considere usar interfaces si cualquiera de estas afirmaciones se aplica a su situación:

Esperas que las clases no relacionadas implementen tu interfaz. Por ejemplo, las interfaces Comparable y Cloneable son implementadas por muchas clases no relacionadas.

Desea especificar el comportamiento de un tipo de datos particular, pero no le preocupa quién implementa su comportamiento.

Desea aprovechar la herencia múltiple de tipo.

De los tutoriales de Oracle :

A diferencia de las interfaces, las clases abstractas pueden contener campos que no son static y final , y pueden contener métodos implementados. Dichas clases abstractas son similares a las interfaces, excepto que proporcionan una implementación parcial, dejándola en subclases para completar la implementación. Si una clase abstracta contiene solo declaraciones de métodos abstractos, debe declararse como una interfaz.

Se pueden implementar múltiples interfaces por clases en cualquier parte de la jerarquía de clases, independientemente de si están relacionadas entre sí de alguna manera. Piense en Comparable o Cloneable , por ejemplo.

En comparación, las clases abstractas se subclasan más comúnmente para compartir piezas de implementación . Una clase abstracta única se subclasifica por clases similares que tienen mucho en común (las partes implementadas de la clase abstracta), pero también tienen algunas diferencias (los métodos abstractos).

Se pueden implementar muchos casos en ambos tipos de clases.

Las interfaces son útiles cuando se quiere definir una clase que debe tener al menos funciones básicas. Como una interfaz real, por ejemplo, USB.

 interface USB { public function sendPower(); //charge iphone for example public function sendData(); //itunes public function recieveData(); } 

Use clases abstractas cuando hay varias formas de implementar un objeto.

 abstract class MobilePhone { public function isIphone(); public function charge() { //get some power, all phones need that } } class iPhone extends MobilePhone { public function isIphone() { return true; } } 

Hay un número de veces que podría considerar usar una interfaz sobre una implementación abstracta

  • Cuando la implementación abstracta disponible no hace lo que desea y desea crear su propia
  • cuando tienes una clase existente (que se extiende desde otra clase) y quieres implementar la funcionalidad de la interfaz

En términos generales, se introdujeron interfaces para superar la falta de herencias múltiples, entre otras cosas

Con soporte de métodos predeterminados en la interfaz desde el lanzamiento de Java 8, la brecha entre la interfaz y las clases abstractas se ha reducido, pero aún tienen grandes diferencias.

  1. Las variables en la interfaz son públicas estáticas finales . Pero la clase abstracta puede tener otro tipo de variables como privado, protegido, etc.

  2. Los métodos en la interfaz son públicos o estáticos, pero los métodos en la clase abstracta pueden ser privados y también protegidos

  3. Use la clase abstracta para establecer la relación entre los objetos interrelacionados. Use la interfaz para establecer la relación entre clases no relacionadas.

Eche un vistazo a este artículo para conocer las propiedades especiales de la interfaz en Java 8. El modificador estático para los métodos predeterminados en la interfaz provoca un error de tiempo de comstackción en el error derivado si desea utilizar @override.

Este artículo explica por qué se introdujeron los métodos predeterminados en java 8: para mejorar la API de colecciones en Java 8 para admitir expresiones lambda.

Eche un vistazo a la documentación de Oracle también para entender las diferencias de una mejor manera.

Eche un vistazo a estas preguntas relacionadas de SE con ejemplos de código para comprender mejor las cosas:

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

Blog de referencia: https://mybolder.com/2015/12/02/when-to-use-abstract-class-and-intreface/

¿Cuál debería usar, clases abstractas o interfaces?

Considere usar clases abstractas si alguna de estas afirmaciones se aplica a su situación:

  1. Desea compartir el código entre varias clases estrechamente relacionadas.
  2. Espera que las clases que amplían 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. Esto le permite definir métodos que pueden acceder y modificar el estado del objeto al que pertenecen.

Considere usar interfaces si cualquiera de estas afirmaciones se aplica a su situación:

  1. Esperas que las clases no relacionadas implementen tu interfaz. Por ejemplo, las interfaces Comparable y Cloneable son implementadas por muchas clases no relacionadas.
  2. Desea especificar el comportamiento de un tipo de datos particular, pero no le preocupa quién implementa su comportamiento.
  3. Desea aprovechar la herencia múltiple de tipo.

Un ejemplo de una clase abstracta en el JDK es AbstractMap , que es parte del marco de colecciones. Sus subclases (que incluyen HashMap , TreeMap y ConcurrentHashMap ) comparten muchos métodos (incluidos get , put , isEmpty , containsKey y containsValue ) que define AbstractMap .

Considerando Java:

Interfaces:

  • Son una abstracción fundamental de OOP.
  • Con frecuencia (pero no siempre) obtendrá un código más claro que las clases abstractas.
  • Puede ser implementado por múltiples clases concretas para adaptarse a diferentes situaciones.
  • Puede implementar directamente escenarios que requieren herencia múltiple.
  • Se puede burlar más fácilmente con fines de prueba.
  • Son útiles para los proxies JDK (vea java.lang.reflect.Proxy).

Estos son solo el comienzo de una lista muy larga de pros / contras para interfaces vs. clases abstractas.

Este es un extracto directo del excelente libro ‘ Thinking in Java ‘ de Bruce Eckel.

[..] ¿Deberías usar una interfaz o una clase abstracta ?

Bueno, una interfaz le brinda los beneficios de una clase abstracta y los beneficios de una interfaz, por lo que si es posible crear su clase base sin ninguna definición de método o variable miembro, siempre debe preferir las interfaces a las clases abstractas.

De hecho, si sabe que algo va a ser una clase base, su primera opción debe ser convertirla en una interfaz, y solo si se ve obligado a tener definiciones de métodos o variables de miembros, debe cambiar a una clase abstracta.

Utilice una clase abstracta cuando quiera definir una plantilla para un grupo de subclases, y tenga al menos algún código de implementación que las subclases de llamadas puedan usar.

Use una interfaz cuando quiera definir el rol que pueden jugar otras clases, independientemente de dónde estén esas clases en el árbol de herencia

extiendes una clase abstracta

implementa una interfaz 🙂

en una interfaz, todos los campos son automáticamente public static y todos los métodos son public mientras que una clase abstracta le permite un poco de flexibilidad aquí.

Las clases abstractas pueden contener métodos que no son abstractos, mientras que en las interfaces todos sus métodos son abstractos y deben implementarse.

En su lugar, debe usar interfaces cuando sabe que siempre implementará esos métodos determinados. También puedes heredar desde múltiples interfaces, es la forma en que java trata con la herencia múltiple

la interfaz se usa básicamente cuando dos partes trabajan juntas, y una de las partes quiere ocultar algo de otra (o solo quiere mostrar una parte de su clase) .que usamos una interfaz, por ejemplo. en jdbc, los proveedores de jdbc nos proporcionan algunas interfaces porque quieren ocultarnos todo.

la clase abstracta solo se usa en ese caso cuando queremos apoyar un comportamiento común en más de una clase … o queremos proporcionar alguna implementación preimplementada con algunos métodos no implementados (los métodos deben ser abstractos). p.ej. http servlet en la interfaz de servlet es una clase abstracta porque esta clase implementa la interfaz de servlet, excepto su método de servicio … por lo que esta clase nos ayuda a obtener una cierta preimplementación del método de interfaz …

En realidad, la interfaz y la clase abstracta se utilizan para especificar algunos contratos / reglas que mostrarán cómo serán sus subclases.

Sobre todo, sabemos que la interfaz es un resumen puro. Significa que no se puede especificar un solo método con el cuerpo. Este punto particular son las ventajas de la clase abstracta. Significa en la clase abstracta que tiene derecho a especificar el método con el cuerpo y sin cuerpo así.

Entonces, si quieres especificar algo sobre tu subclase, entonces puedes optar por la interfaz. Pero si también quieres especificar algo para tus subclases y quieres también tu clase también debe tener algún método propio. Luego, en ese caso, puedes optar por la clase abstracta.

No se puede lograr una herencia múltiple con clase abstracta, por eso el microsistema solar proporciona interfaces.

No puede extender dos clases pero puede implementar múltiples interfaces

Interface y Abstract Class son las dos formas diferentes de lograr abstracción en lenguajes OOP.

La interfaz proporciona 100% abstracción del 100% , es decir, todos los métodos son abstractos.

La clase abstracta proporciona una abstracción de 0 to 100% , es decir, puede tener o no métodos abstractos.

Podemos usar la Interface cuando queremos que el cliente implemente toda la funcionalidad de un tipo.

Podemos utilizar la Abstract Class cuando el implementador de la Abstract Class puede proporcionar alguna funcionalidad común y el cliente tendrá la oportunidad de implementar lo que realmente necesita.

Clase abstracta : Úselo cuando exista una relación fuerte entre superclase y subclase y todas las subclases comparten algún comportamiento común.

Interfaz : Define solo el protocolo que todas las subclases deben seguir.

La respuesta a esta pregunta es muy simple: todo lo que podemos hacer con la interfaz se puede hacer con la clase abstracta De acuerdo … así que cuando se usan interfaces, la respuesta está en la restricción C # de la herencia múltiple. Cuando solo tiene contratos (resúmenes) para declarar y quiere que sus subclases lo implementen, vaya con las interfaces, porque si utiliza la clase abstracta en este caso, no puede heredar de una clase más y está atascado si desea heredar de una. más clase, pero puede implementar tantas interfaces.

Si está utilizando JDK 8, no hay ninguna razón para usar clases abstractas porque, hagamos lo que hagamos con las clases abstractas, ahora podemos hacerlo con interfaces debido a los métodos predeterminados. Si usa la clase abstracta, debe extenderla y existe una restricción que puede extenderse solo una vez. Pero si usas la interfaz puedes implementar tantas como quieras.

La interfaz es por defecto una clase abstracta y todos los métodos y constructores son públicos.

Encontré esta muy buena explicación aquí espero que ayude a alguien. léelo aquí

Las interfaces y las clases abstractas parecen muy similares, sin embargo, existen diferencias importantes entre ellas.

La abstracción se basa en una buena relación ” es-a “. Lo que significa que dirías que un automóvil es un Honda y un Honda es un automóvil. Usar la abstracción en una clase significa que también puedes tener métodos abstractos. Esto requeriría que cualquier subclase extendida desde ella obtenga los métodos abstractos y los anule. Usando el ejemplo a continuación, podemos crear un resumen howToStart (); método que requerirá que cada clase lo implemente.

A través de la abstracción, podemos proporcionar similitudes entre códigos, por lo que aún tendríamos una clase base. Usando un ejemplo de la idea de la clase Car, podríamos crear:

 public abstract class Car{ private String make; private String model protected Car() { } // Default constructor protect Car(String make, String model){ //Assign values to } public abstract void howToStart(); } 

Luego, con la clase de Honda, tendríamos:

 public class Honda extends implements Engine { public Honda() { } // Default constructor public Honda(String make, String model){ //Assign values } @Override public static void howToStart(){ // Code on how to start } } 

Las interfaces se basan en la relación “tiene-a”. Esto significaría que podría decirse que un automóvil tiene un motor, pero un motor no es un automóvil. En el ejemplo anterior, Honda ha implements Engine .

Para la interfaz del motor podríamos crear:

 public interface Engine { public void startup(); } 

La interfaz proporcionará una instancia de muchos a uno. Entonces podríamos aplicar la interfaz del motor a cualquier tipo de automóvil. También podemos extenderlo a otro objeto. Como si tuviéramos que hacer una clase de barco, y tuviésemos subclases de tipos de barco, podríamos ampliar el motor y tener las subclases del barco que requieren el startup(); método. Las interfaces son buenas para crear un marco para varias clases que tienen algunas similitudes. También podemos implementar instancias múltiples en una clase, como:

 public class Honda extends implements Engine, Transmission, List 

Espero que esto ayude.

Si se encuentra en una situación en la que la implementación de su método de interfaz es la misma para todas las clases de inercia, entonces no necesita interfaz, en su lugar debería haberse utilizado la clase abstracta. Cuando desee que cada clase siga (debe tener) algo y la implementación diferirá o no se definirá, entonces optaremos por la interfaz.