una sirve que puede para multiple interfaces implementacion herencia heredar ejercicios ejemplos clases clase abstractas abstracta java oop inheritance interface multiple-inheritance

java - puede - para que sirve una clase abstracta



¿Por qué utilizar interfaces, herencia múltiple frente a interfaces, ventajas de las interfaces? (11)

Todavía tengo algo de confusión sobre esto. Lo que he encontrado hasta ahora es

(Ya se han hecho preguntas similares aquí pero tenía algunos otros puntos).

  1. Interface es una colección de ÚNICAMENTE métodos abstractos y campos finales.

  2. No hay herencia múltiple en Java.

  3. Las interfaces se pueden usar para lograr herencia múltiple en Java.

  4. Un punto fuerte de la herencia es que podemos usar el código de la clase base en la clase derivada sin escribirlo de nuevo. Puede ser que esto sea lo más importante para que la herencia esté allí.

Ahora..

Q1. Como las interfaces tienen solo métodos abstractos (sin código), ¿cómo podemos decir que si implementamos una interfaz, entonces es herencia? No estamos usando su código.

Q2. Si la implementación de una interfaz no es herencia, ¿cómo se utilizan las interfaces para lograr herencia múltiple?

Q3. De todos modos, ¿cuál es el beneficio de usar interfaces? Ellos no tienen ningún código. Necesitamos escribir el código una y otra vez en todas las clases que implementamos.

Entonces, ¿por qué hacer interfaces?

NOTA: He encontrado un caso en el que las interfaces son útiles. Un ejemplo es que en la interfaz de Runnable tenemos el método public void run () en el que definimos la funcionalidad del hilo y hay una codificación incorporada que indica que este método se ejecutará como un hilo separado. Entonces solo necesitamos codificar qué hacer en el hilo, Rest está predefinido. Pero esto también se puede lograr usando clases abstractas y todo.

Entonces, ¿cuáles son los beneficios exactos del uso de interfaces? ¿Es realmente una Herencia Múltiple que logramos usar Interfaces?


Q1. Como las interfaces tienen solo métodos abstractos (sin código), ¿cómo podemos decir que si implementamos una interfaz, entonces es herencia? No estamos usando su código.

Desafortunadamente, en el uso coloquial, la palabra inheritance aún se utiliza con frecuencia cuando una clase implementa una interfaz, aunque la interface implementation sería un término preferible: OMI, el término inheritance debe usarse estrictamente con la herencia de una clase concreta o abstracta. En lenguajes como C ++ y C #, la misma sintaxis (es decir, Subclass : Superclass y Class : Interface ) se usa tanto para herencia de clase como para implementación de interfaz, lo que puede haber contribuido a la diseminación del mal uso de la palabra inheritance con interfaces. Java tiene una sintaxis diferente para extend una clase en lugar de implement una interfaz, lo cual es algo bueno.

Q2 Si la implementación de una interfaz no es herencia, ¿cómo se utilizan las interfaces para lograr herencia múltiple?

Puede lograr el "efecto" de la herencia múltiple a través de la composición, implementando múltiples interfaces en una clase y luego proporcionando implementaciones para todos los métodos, propiedades y eventos requeridos de todas las interfaces en la clase. Una técnica común de hacer esto con clases concretas es hacer relaciones ''has-a'' (composición) con clases que implementan las interfaces externas ''conectando'' la implementación con cada una de las implementaciones de clases internas. (Los lenguajes como C ++ son compatibles con la herencia concreta múltiple directamente, pero que crea otros problemas potenciales como el problema del diamante).

Q3 De todos modos, ¿cuál es el beneficio de usar interfaces? Ellos no tienen ningún código. Necesitamos escribir el código una y otra vez en todas las clases que implementamos.

Las interfaces permiten que las clases existentes (por ejemplo, los marcos) interactúen con sus nuevas clases sin haberlas visto antes, debido a la capacidad de comunicarse a través de una interfaz conocida. Piensa en una interfaz como un contrato. Al implementar esta interfaz en una clase, usted está obligado contractualmente a cumplir con las obligaciones que se le exigen, y una vez que se implemente este contrato, su clase debería poder usarse indistintamente con cualquier otro código que consuma la interfaz.

Ejemplo de mundo real

Un ejemplo del "mundo real" sería la legislación y la convención (interfaz) que rodea una toma de corriente eléctrica en un país en particular. Cada artefacto eléctrico enchufado en el zócalo debe cumplir con las especificaciones (contrato) que las autoridades han definido para el zócalo, por ejemplo, el posicionamiento de la línea, neutro y cables de tierra, la posición y coloración del interruptor de encendido / apagado y la conformidad el voltaje eléctrico, la frecuencia y la corriente máxima que se suministrarán a través de la interface cuando esté encendida.

El beneficio de desacoplamiento de la interfaz (es decir, un enchufe de pared estándar) en lugar de simplemente soldar cables juntos es que puede enchufar (y desconectar) un ventilador, un hervidor, un adaptador doble o algún dispositivo nuevo que se inventará el próximo año en él. , aunque este dispositivo no existía cuando se diseñó la interfaz. ¿Por qué? Porque se ajustará a los requisitos de la interfaz.

¿Por qué usar interfaces?

Las interfaces son excelentes para el acoplamiento flexible de clases, y son uno de los pilares del paradigma SOLID del Tío Bob, especialmente el Dependency Inversion Principle y los Interface Segregation Principles .

En pocas palabras, al asegurar que las dependencias entre clases estén acopladas solo en interfaces (abstracciones), y no en otras clases concretas, permite que la dependencia sea sustituida por cualquier otra implementación de clase que cumpla con los requisitos de la interfaz.

En las pruebas, los resguardos y las burlas de las dependencias se pueden usar para probar la unidad de cada clase, y la interacción que la clase tiene con la dependencia se puede ''espiar''.


Q1. Como las interfaces tienen solo métodos abstractos (sin código), ¿cómo podemos decir que si implementamos una interfaz, entonces es herencia? No estamos usando su código.

No podemos. Las interfaces no se usan para lograr herencia múltiple. Lo reemplazan con una construcción más segura, aunque un poco menos poderosa. Tenga en cuenta que la palabra clave implements lugar de se extends .

Q2. Si la implementación de una interfaz no es herencia, ¿cómo se utilizan las interfaces para lograr herencia múltiple?

Ellos no son. Con las interfaces, una sola clase puede tener varias " vistas ", diferentes API o capacidades. Por ejemplo, una clase puede ser Runnable e Callable al mismo tiempo, mientras que ambos métodos están haciendo efectivamente lo mismo.

Q3. De todos modos, ¿cuál es el beneficio de usar interfaces? Ellos no tienen ningún código. Necesitamos escribir el código una y otra vez en todas las clases que implementamos.

Las interfaces son tipo de herencia múltiple sin problemas que este último introduce (como el problema Diamante ).

Hay pocos casos de uso para interfaces:

  1. El objeto tiene efectivamente dos identidades: un Tank es tanto un Vehicle como un Weapon . Puede usar una instancia de Tank donde se espera el primero o el último (polimorfismo). Esto rara vez es un caso en la vida real y en realidad es un ejemplo válido en el que la herencia múltiple sería mejor (o los rasgos).

  2. Responsabilidades simples: una instancia del objeto Tank en un juego también es Runnable para permitirle ejecutarlo en un hilo y un ActionListener para responder a los eventos del mouse.

  3. Interfaces de devolución de llamada: si el objeto implementa una interfaz de devolución de llamada dada, recibe una notificación sobre su ciclo de vida u otros eventos.

  4. Interfaces de marcador: sin agregar ningún método, pero de fácil acceso a través de instanceof para descubrir capacidades o deseos de objetos. Serializable y Cloneable son ejemplos de esto.

Lo que estás buscando es rasgo (como en Scala), desafortunadamente no disponible en Java.


Interfaces

Una interfaz es un contrato que define cómo interactuar con un objeto. Son útiles para expresar cómo sus internos tienen la intención de interactuar con un objeto. Después de la Inversión de Dependencia, tu API pública tendrá todos los parámetros expresados ​​con interfaces. No le importa cómo hace lo que necesita hacer, solo que hace exactamente lo que necesita hacer.

Ejemplo: Puede que simplemente necesite un Vehicle para transportar mercancías, no le importa el modo de transporte particular.

Herencia

La herencia es una extensión de una implementación particular. Esa implementación puede o no satisfacer una interfaz particular. Debería esperar un ancestro de una implementación particular solo cuando le importa cómo.

Ejemplo: es posible que necesite una implementación en Plane de un vehículo para un transporte rápido.

Composición

La composición se puede usar como una alternativa a la herencia. En lugar de que su clase extienda una clase base, se crea con objetos que implementan porciones más pequeñas de la responsabilidad de la clase principal. La composición se usa en el facade pattern y el decorator pattern .

Ejemplo: Puede crear una DuckBoat ( DUKW ) que implemente LandVehicle y WaterVehicle que implementen Vehicle compuesto por implementaciones de Truck y Boat .

Respuestas

Q1. Como las interfaces tienen solo métodos abstractos (sin código), ¿cómo podemos decir que si implementamos una interfaz, entonces es herencia? No estamos usando su código.

Las interfaces no son herencia. La implementación de una interfaz expresa que tiene la intención de que su clase opere de la manera definida por la interfaz. La herencia es cuando tienes un ancestro común, y recibes el mismo comportamiento ( inherit ) que el ancestro, por lo que no necesitas definirlo.

Q2. Si la implementación de una interfaz no es herencia, ¿cómo se utilizan las interfaces para lograr herencia múltiple?

Las interfaces no logran herencia múltiple. Expresan que una clase puede ser adecuada para múltiples roles.

Q3. De todos modos, ¿cuál es el beneficio de usar interfaces? Ellos no tienen ningún código. Necesitamos escribir el código una y otra vez en todas las clases que implementamos.

Uno de los principales beneficios de las interfaces es proporcionar una separación de preocupaciones:

  • Puedes escribir una clase que haga algo con otra clase sin importar cómo se implementa esa clase.
  • Cualquier desarrollo futuro puede ser compatible con su implementación sin necesidad de extender una clase base particular.

In the spirit of DRY you can write an implementation that satisfies an interface and change it while still respecting the open/closed principal if you leverage composition.


Ambos métodos funcionan (interfaces y herencia múltiple).

Rápida respuesta corta práctica

Las interfaces son mejores cuando tiene varios años de experiencia en el uso de Herencias Múltiples que tienen Súper Clases con solo definición de método, y ningún código en absoluto.

Una pregunta complementaria puede ser: "Cómo y por qué migrar el código de las clases abstractas a las interfaces".

Si no tiene muchas clases abstractas, puede omitir las interfaces.

No te apresures a usar interfaces.

Respuesta larga aburrida

Las interfaces son muy similares, o incluso equivalentes a Clases abstractas.

Si su código tiene muchas clases abstractas, entonces es hora de que empiece a pensar en términos de interfaces.

El siguiente código con clases abstractas:

MyStreamsClasses.java

/* File name : MyStreamsClasses.java */ import java.lang.*; // Any number of import statements public abstract class InputStream { public void ReadObject(Object MyObject); } public abstract class OutputStream { public void WriteObject(Object MyObject); } public abstract class InputOutputStream imnplements InputStream, OutputStream { public void DoSomethingElse(); }

Puede ser reemplazado por:

MyStreamsInterfaces.java

/* File name : MyStreamsInterfaces.java */ import java.lang.*; // Any number of import statements public interface InputStream { public void ReadObject(Object MyObject); } public interface OutputStream { public void WriteObject(Object MyObject); } public interface InputOutputStream extends InputStream, OutputStream { public void DoSomethingElse(); }

Aclamaciones.


La herencia es cuando una clase se deriva de otra clase (que puede ser abstracta) o una interfaz. El punto más fuerte orientado a objetos (herencia) no es la reutilización de código (hay muchas formas de hacerlo), sino el polimorfismo.

El polimorfismo se produce cuando se tiene un código que usa la interfaz, y su objeto de instancia puede ser de cualquier clase derivada de esa interfaz. Por ejemplo, puedo tener dicho método: public void Pet (IAnimal animal) y este método obtendrá un objeto que es una instancia de Dog o Cat que hereda de IAnimal. o puedo tener un código así: IAnimal animal y luego puedo llamar a un método de esta interfaz: animal.Eat () que Dog o Cat pueden implementar de una manera diferente.

La principal ventaja de las interfaces es que puede heredar de algunas de ellas, pero si necesita heredar de una sola también puede usar una clase abstracta. Aquí hay un artículo que explica más sobre las diferencias entre una clase abstracta y una interfaz: http://www.codeproject.com/KB/cs/abstractsvsinterfaces.aspx


Las interfaces se crean para que una clase implemente la funcionalidad dentro de la interfaz y se comporte de acuerdo con esa interfaz.


Las interfaces son una colección de campos estáticos finales y métodos abstractos (Nuevamente Java 8 agregó soporte para tener métodos estáticos en una interfaz).

Las interfaces se crean en situaciones en las que sabemos que se debe hacer alguna tarea, pero cómo debe hacerse puede variar. En otras palabras, podemos decir que implementamos interfaces para que nuestra clase comience a comportarse de una manera particular.

Permítanme explicarles con un ejemplo, todos sabemos qué son los animales. Como Lion es un animal, el mono es un animal, el elefante es un animal, la vaca es un animal, etc. Ahora sabemos que todos los animales comen algo y duermen. Pero la forma en que cada animal puede comer algo o dormir puede diferir. Al igual que León come cazando otros animales donde la vaca come hierba. Pero ambos comen. Entonces podemos tener un pseudo código como este,

interface Animal { public void eat(); public void sleep(); } class Lion implements Animal { public void eat() { // Lion''s way to eat } public void sleep(){ // Lion''s way to sleep } } class Monkey implements Animal { public void eat() { // Monkey''s way to eat } public void sleep() { // Monkey''s way to sleep } }

Según el pseudo código mencionado anteriormente, cualquier cosa que sea capaz de comer o dormir se llamará animal o podemos decir que es obligatorio para todos los animales comer y dormir, pero la forma de comer y dormir depende del animal.

En el caso de las interfaces, heredamos solo el comportamiento, no el código real como en el caso de la herencia de las clases.

Q1. Como las interfaces tienen solo métodos abstractos (sin código), ¿cómo podemos decir que si implementamos una interfaz, entonces es herencia? No estamos usando su código.

La implementación de interfaces es otro tipo de herencia. No es similar a la herencia de las clases, ya que en esa herencia la clase hija obtiene el código real para reutilizar de la clase base.

Q2. Si la implementación de una interfaz no es herencia, ¿cómo se utilizan las interfaces para lograr herencia múltiple?

Se dice porque una clase puede implementar más de una interfaz. Pero tenemos que entender que esta herencia es diferente a la herencia de las clases.

Q3. De todos modos, ¿cuál es el beneficio de usar interfaces? Ellos no tienen ningún código. Necesitamos escribir el código una y otra vez en todas las clases que implementamos.

La implementación de una interfaz impone la obligación a la clase de que debe anular todos sus métodos abstractos.

Lea más en mi libro here y here


Vieja pregunta Me sorprende que nadie haya citado las fuentes canónicas: Java: una descripción general de James Gosling, Patrones de diseño: elementos de software reutilizable orientado a objetos por la pandilla de los cuatro o Java efectivo por Joshua Bloch (entre otras fuentes).

Comenzaré con una cita:

Una interfaz es simplemente una especificación de un conjunto de métodos a los que responde un objeto. No incluye ninguna variable de instancia o implementación. Las interfaces se pueden heredar de forma múltiple (a diferencia de las clases) y se pueden usar de una manera más flexible que la estructura rígida de herencia de clase habitual. (Gosling, p.8)

Ahora, tomemos sus suposiciones y preguntas una por una (voluntariamente ignoraré las características de Java 8).

Suposiciones

Interface es una colección de ÚNICAMENTE métodos abstractos y campos finales.

¿Viste la palabra clave abstract en las interfaces de Java? No. Entonces no debería considerar una interfaz como una colección de métodos abstractos. Tal vez esté mal guiado por las llamadas interfaces de C ++, que son clases con solo métodos virtuales puros. C ++, por diseño, no tiene (y no necesita tener) interfaces, porque tiene herencia múltiple.

Como explicó Gosling, debería considerar una interfaz como "un conjunto de métodos a los que responde un objeto". Me gusta ver una interfaz y la documentación asociada como un contrato de servicio. Describe lo que puede esperar de un objeto que implementa esa interfaz. La documentación debe especificar las condiciones previa y posterior (por ejemplo, los parámetros no deben ser nulos, la salida siempre es positiva, ...) y las invariantes (un método que no modifica el estado interno del objeto). Este contrato es el corazón, creo, de OOP.

No hay herencia múltiple en Java.

En efecto.

JAVA omite muchas características poco utilizadas, poco entendidas y confusas de C ++ que en nuestra experiencia traen más dolor que beneficio. Esto consiste principalmente en la sobrecarga del operador (aunque tiene sobrecarga de método), herencia múltiple y extensas coerciones automáticas. (Gosling, p.2)

Nada que añadir.

Las interfaces se pueden usar para lograr herencia múltiple en Java.

No, simlpy porque no hay herencia múltiple en Java. Véase más arriba.

Un punto fuerte de la herencia es que podemos usar el código de la clase base en la clase derivada sin escribirlo de nuevo. Puede ser que esto sea lo más importante para que la herencia esté allí.

Eso se llama "herencia de implementación". Como escribió, es una forma conveniente de reutilizar el código.

Pero tiene una contraparte importante:

las clases para padres a menudo definen al menos parte de la representación física de sus subclases. Debido a que la herencia expone una subclase a los detalles de la implementación de su padre, a menudo se dice que "la herencia rompe la encapsulación" [Sny86]. La implementación de una subclase se vincula tanto con la implementación de su clase principal que cualquier cambio en la implementación de los padres obligará a la subclase a cambiar. (GOF, 1.6)

(Hay una cita similar en Bloch, artículo 16.)

En realidad, la herencia sirve también para otro propósito:

La herencia de clase combina la herencia de interfaz y la herencia de implementación. La herencia de la interfaz define una nueva interfaz en términos de una o más interfaces existentes. La herencia de implementación define una nueva implementación en términos de una o más implementaciones existentes. (GOF, Apéndice A)

Ambos usan la palabra clave extends en Java. Puede tener jerarquías de clases y jerarquías de interfaces. Los primeros comparten la implementación, los segundos comparten la obligación.

Preguntas

Q1. Como las interfaces tienen solo métodos abstractos (sin código), ¿cómo podemos decir que si implementamos una interfaz, entonces es herencia? No estamos usando su código. **

La implementación de una interfaz no es herencia. Es implementación. Por lo tanto, la palabra clave se implements .

Q2. Si la implementación de una interfaz no es herencia, ¿cómo se utilizan las interfaces para lograr herencia múltiple? **

Sin herencia múltiple en Java. Véase más arriba.

Q3. De todos modos, ¿cuál es el beneficio de usar interfaces? Ellos no tienen ningún código. Necesitamos escribir código una y otra vez en todas las clases que lo implementamos. / ¿Entonces por qué hacer interfaces? / ¿Cuáles son los beneficios exactos del uso de interfaces? ¿Es realmente una Herencia Múltiple que logramos usar Interfaces?

La pregunta más importante es: ¿por qué le gustaría tener herencia múltiple? Puedo pensar en dos respuestas: 1. dar varios tipos a un objeto; 2. para reutilizar el código.

Da varios tipos a un objeto

En OOP, un objeto puede tener diferentes tipos . Por ejemplo, en Java, una ArrayList<E> tiene los siguientes tipos: Serializable , Cloneable , Iterable<E> , Collection<E> , List<E> , RandomAccess , AbstractList<E> , AbstractCollection<E> y Object (Espero No he olvidado a nadie). Si un objeto tiene diferentes tipos, varios consumidores podrán usarlo sin tener en cuenta sus especificidades. Necesito una Iterable<E> y me das una ArrayList<E> ? Está bien. Pero si ahora necesito una List<E> y me das una ArrayList<E> , también está bien. Etc.

¿Cómo se escribe un objeto en OOP? Tomó la interfaz Runnable como ejemplo, y este ejemplo es perfecto para ilustrar la respuesta a esta pregunta. Cito el documento oficial de Java:

Además, Runnable proporciona los medios para que una clase esté activa sin subclasificar el hilo.

Este es el punto: la herencia es una forma conveniente de escribir objetos. ¿Quieres crear un hilo? Subclasemos la clase Thread . Desea que un objeto tenga diferentes tipos, usemos la herencia mutliple. Argh. No existe en Java. (En C ++, si desea que un objeto tenga diferentes tipos, la herencia múltiple es el camino a seguir).

¿Cómo dar múltiples tipos a un objeto, entonces? En Java, puede escribir su objeto directamente . Eso es lo que haces cuando tu clase implements la interfaz Runnable . ¿Por qué utilizar Runnable si Runnable un entusiasta de la herencia? Tal vez porque su clase ya es una subclase de otra clase, digamos A Ahora su clase tiene dos tipos: A y Runnable .

Con múltiples interfaces, puede dar múltiples tipos a un objeto. Solo tienes que crear una clase que implements múltiples interfaces. Siempre y cuando cumpla con los contratos, está bien.

Código de reutilización

Este es un tema difícil; Ya he citado al GOF para romper la encapsulación. Otra respuesta mencionó el problema del diamante. También podría pensar en el Principio de Responsabilidad Individual:

Una clase debe tener solo una razón para cambiar. (Robert C. Martin, Desarrollo ágil de software, Principios, patrones y prácticas)

Tener una clase para padres puede darle a la clase una razón para cambiar, además de sus propias responsabilidades:

La implementación de la superclase puede cambiar de una versión a otra, y si lo hace, la subclase puede romperse, aunque no se haya tocado su código. Como consecuencia, una subclase debe evolucionar en tándem con su superclase (Bloch, elemento 16).

Añadiría un tema más prosaico: siempre tengo una sensación extraña cuando trato de encontrar el código fuente de un método en una clase y no puedo encontrarlo. Entonces recuerdo: debe definirse en algún lugar de la clase para padres. O en la clase de abuelos. O tal vez incluso más alto. Un buen IDE es un activo valioso en este caso, pero sigue siendo, en mi opinión, algo mágico. Nada similar con jerarquías de interfaces, ya que el javadoc es lo único que necesito: un atajo de teclado en el IDE y lo obtengo.

La herencia sin embargo tiene ventajas:

Es seguro utilizar la herencia dentro de un paquete, donde las implementaciones de subclase y superclase están bajo el control de los mismos programadores. También es seguro usar la herencia cuando se extienden clases específicamente diseñadas y documentadas para la extensión (Elemento 17: Diseñar y documentar por herencia o prohibirlo). (Bloch, elemento 16)

Un ejemplo de una clase "específicamente diseñada y documentada para la extensión" en Java es AbstractList .

Pero Bloch y GOF insisten en esto: "Favorecer la composición sobre la herencia":

La delegación es una forma de hacer que la composición sea tan poderosa para la reutilización como herencia [Lie86, JZ91]. En la delegación, dos objetos están involucrados en el manejo de una solicitud: un objeto receptor delega operaciones a su delegado. Esto es análogo a las subclases que difieren las solicitudes a las clases principales. (GOF p.32)

Si usa la composición, no tendrá que escribir el mismo código una y otra vez. Simplemente crea una clase que maneja las duplicaciones y pasa una instancia de esta clase a las clases que implementan la interfaz. Es una forma muy simple de reutilizar el código. Y esto le ayuda a seguir el Principio de Responsabilidad Individual y hacer que el código sea más comprobable. Rust and Go no tiene herencia (tampoco tienen clases), pero no creo que el código sea más redundante que en otros lenguajes OOP.

Además, si utiliza la composición, se encontrará naturalmente utilizando interfaces para darle a su código la estructura y la flexibilidad que necesita (consulte otras respuestas en los casos de uso de interfaces).

Nota: puede compartir el código con las interfaces Java 8

Y finalmente, una última cita:

Durante la memorable sesión de preguntas y respuestas, alguien le preguntó [a James Gosling]: "Si pudieras hacer Java una vez más, ¿qué cambiarías?" "Dejaría las clases" (en cualquier lugar de la red, no sé si esto es cierto)


Esta es una pregunta muy antigua y la versión java-8 ha agregado más funciones y más poder para la interfaz.

Una declaración de interfaz puede contener

  1. firmas de métodos
  2. métodos predeterminados
  3. métodos estáticos
  4. definiciones constantes.

Los únicos métodos que tienen implementaciones en la interfaz son los métodos predeterminados y estáticos .

Usos de la interfaz:

  1. Para definir un contrato
  2. Para vincular las clases no relacionadas con tiene una capacidad (por ejemplo, las clases que implementan la interfaz Serializable pueden o no tener ninguna relación entre ellas, excepto la implementación de esa interfaz
  3. Para proporcionar una implementación intercambiable , por ejemplo Strategy_pattern
  4. los métodos predeterminados le permiten agregar nuevas funcionalidades a las interfaces de sus bibliotecas y asegurar la compatibilidad binaria con el código escrito para versiones anteriores de esas interfaces
  5. Organice métodos de ayuda en sus bibliotecas con métodos estáticos (puede mantener métodos estáticos específicos para una interfaz en la misma interfaz en lugar de en una clase separada)

Eche un vistazo a esta pregunta relacionada de SE para ejemplos de códigos para comprender mejor los conceptos:

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

Volviendo a sus consultas:

Q1. Como las interfaces tienen solo métodos abstractos (sin código), ¿cómo podemos decir que si implementamos una interfaz, entonces es herencia? No estamos usando su código.

Q2. Si la implementación de una interfaz no es herencia, ¿cómo se utilizan las interfaces para lograr herencia múltiple?

La interfaz puede contener código para métodos estáticos y predeterminados . Estos métodos predeterminados proporcionan compatibilidad hacia atrás y los métodos estáticos proporcionan funciones auxiliares / de utilidad .

No se puede tener una herencia múltiple verdadera en Java y la interfaz no es la manera de obtenerlo. La interfaz solo puede contener constantes. Entonces no puedes heredar el estado pero puedes implementar el comportamiento.

Puede reemplazar herencia con capacidad . La interfaz proporciona múltiples capacidades para implementar clases.

Q3. De todos modos, ¿cuál es el beneficio de usar interfaces? Ellos no tienen ningún código. Necesitamos escribir el código una y otra vez en todas las clases que implementamos.

Consulte la sección " usos de la interfaz " en mi respuesta.


BESO

He buscado durante días, incluso semanas tratando de comprender las interfaces y parece que he leído la misma ayuda genérica; No estoy tratando de menospreciar las contribuciones, pero creo que la bombilla simplemente hizo clic, así que estoy feliz :)

Prefiero mantenerlo simple y estúpido, así que ofreceré mi nueva vista de interfaces encontrada.

Soy un codificador casual, pero quiero publicar este código que escribí en VB.NET (el principio es el mismo para otros idiomas), para ayudar a otros a entender las interfaces.

Si lo tengo mal, infórmeselo a los demás en los comentarios de seguimiento.

Explicación

Tres botones en un formulario, al hacer clic en cada uno, guarda una referencia de clase diferente a la variable de interfaz (_data). El punto de referencias de clase diferentes en una variable de interfaz, es lo que no entendí, ya que parecía redundante, entonces su poder se vuelve evidente con el msgbox, solo necesito llamar al MISMO método para realizar la tarea que necesito, en este case ''GetData ()'', que usa el método en la clase que actualmente tiene la variable de referencia de interfaz (_data).

Así que, sin embargo, deseo obtener mis datos (de una base de datos, de la web o de un archivo de texto), solo se hace utilizando el mismo nombre de método ; el código detrás de esa implementación ... no me importa.

Entonces es fácil cambiar cada código de clase usando la interfaz sin ninguna dependencia ... este es un objetivo clave en OO y encapsulación.

Cuándo usar

Clases de código y si observa el mismo verbo utilizado para métodos, como ''GetData ()'', entonces es un buen candidato para implementar una interfaz en esa clase y usar ese nombre de método como una abstracción / interfaz.

Sinceramente espero que esto ayude a un compañero novato con este difícil principio.

Public Class Form1 Private _data As IData = Nothing Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click _data = New DataText() MsgBox(_data.GetData()) End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click _data = New DataDB() MsgBox(_data.GetData()) End Sub Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click _data = New DataWeb() MsgBox(_data.GetData()) End Sub End Class Public Interface IData Function GetData() As String End Interface Friend Class DataText : Implements IData Friend Function GetData() As String Implements IData.GetData Return "DataText" End Function End Class Friend Class DataDB : Implements IData Friend Function GetData() As String Implements IData.GetData Return "DataDB" End Function End Class Friend Class DataWeb : Implements IData Friend Function GetData() As String Implements IData.GetData Return "DataWeb" End Function End Class


Q1. Como las interfaces solo tienen métodos abstractos (sin código), ¿cómo podemos decir que si estamos implementando una interfaz, entonces es herencia? No estamos usando su código.

No es herencia igual. Es simplemente similar. Dejame explicar:

VolvoV3 extends VolvoV2, and VolvoV2 extends Volvo (Class) VolvoV3 extends VolvoV2, and VolvoV2 implements Volvo (Interface) line1: Volvo v = new VolvoV2(); line2: Volvo v = new VolvoV3();

Si solo ve la línea 1 y la línea 2, puede inferir que VolvoV2 y VolvoV3 tienen el mismo tipo. No se puede inferir si Volvo es una superclase o si Volvo es una interfaz.

Q2. Si la implementación de una interfaz no es herencia, ¿cómo se utilizan las interfaces para lograr herencias múltiples?

Ahora usando interfaces:

VolvoXC90 implements XCModel and Volvo (Interface) VolvoXC95 implements XCModel and Volvo (Interface) line1: Volvo a = new VolvoXC90(); line2: Volvo a = new VolvoXC95(); line3: XCModel a = new VolvoXC95();

Si solo ve la línea 1 y la línea 2, puede inferir que VolvoXC90 y VolvoXC95 tienen el mismo tipo (Volvo). No se puede inferir que Volvo es una superclase o que Volvo es una interfaz.

Si solo ves line2 y line3, puedes inferir que Volvo95 implementa dos tipos, XCModel y Volvo, en Java sabes que al menos uno tiene que ser una interfaz. Si este código se escribió en C ++, por ejemplo, podrían ser ambas clases. Por lo tanto, herencias múltiples.

Q3. De todos modos, ¿cuál es el beneficio de usar interfaces? Ellos no tienen ningún código. Necesitamos escribir el código una y otra vez en todas las clases que implementamos.

Imagina un sistema donde utilizas una clase de VolvoXC90 en otras 200 clases.

VolvoXC90 v = new VolvoXC90();

Si necesita evolucionar su sistema para iniciar VolvoXC95, debe modificar otras 200 clases.

Ahora imagine un sistema en el que usa una interfaz de Volvo en 10,000,000 de clases.

// Create VolvoXC90 but now we need to create VolvoXC95 Volvo v = new VolvoFactory().newCurrentVolvoModel();

Ahora, si necesita evolucionar su sistema para crear modelos VolvoXC95, debe modificar solo una clase, la Fábrica.

Es una pregunta de sentido común. Si su sistema está compuesto solo por pocas clases y tiene pocas actualizaciones, el uso de interfaces en todas partes es contraproducente. Para sistemas grandes, puede ahorrarle mucho dolor y evitar el riesgo de adoptar interfaces.

Te recomiendo que leas más sobre los principios SÓLIDOS y leas el libro Effective Java. Tiene buenas lecciones de ingenieros de software con experiencia.