1. Habilidades
Para comprender mejor los beneficios de las interfaces y dónde usarlas, debemos hablar sobre algunas cosas más abstractas.
Una clase generalmente modela un objeto en particular. Una interfaz corresponde menos a los objetos y más a sus habilidades o roles.
![La esencia de las interfaces](https://cdn.codegym.cc/images/article/32745779-1857-417b-999a-1d00522cc13a/800.jpeg)
Por ejemplo, elementos como automóviles, bicicletas, motocicletas y ruedas se representan mejor como clases y objetos. Pero sus habilidades, como "Me pueden montar", "Puedo transportar personas", "Puedo pararme", se presentan mejor como interfaces. Aquí hay unos ejemplos:
Código | Descripción |
---|---|
|
Corresponde a la capacidad de moverse. |
|
Corresponde a la capacidad de ser montado |
|
Corresponde a la capacidad de transportar cosas. |
|
La Wheel clase puede moverse |
|
La Car clase puede moverse, montarse y transportar cosas. |
|
La Skateboard clase puede moverse y ser montada. |
2. Funciones
Las interfaces simplifican enormemente la vida de un programador. Muy a menudo, un programa tiene miles de objetos, cientos de clases, pero solo un par de docenas de interfaces , es decir, roles . Hay pocos roles, pero hay muchas formas de combinarlos (clases).
El punto es que no tienes que escribir código en cada clase para interactuar con todas las demás clases. Solo necesita interactuar con sus roles (interfaces).
Imagina que eres un entrenador de mascotas. Cada una de las mascotas con las que trabajas puede tener varias habilidades diferentes. Tienes una discusión amistosa con tu vecino sobre qué mascotas pueden hacer más ruido. Para resolver el asunto, simplemente alinea a todas las mascotas que pueden "hablar" y les das la orden: ¡Habla!
No te importa qué tipo de animal son o qué otras habilidades tienen. Incluso si pueden hacer un triple salto mortal hacia atrás. En este momento en particular, solo te interesa su capacidad para hablar en voz alta. Así es como se vería en el código:
Código | Descripción |
---|---|
|
la CanSpeak habilidad Esta interfaz entiende el comando to speak , lo que significa que tiene un método correspondiente. |
|
Animales que tienen esta característica.
Para facilitar la comprensión, proporcionamos los nombres de las clases en inglés. Esto está permitido en Java, pero es altamente indeseable.
|
|
¿Y cómo les damos el mando? |
Cuando el número de clases en tus programas alcance los miles, no podrás vivir sin interfaces. En lugar de describir la interacción de miles de clases, basta con describir la interacción de unas pocas docenas de interfaces; esto simplifica enormemente la vida.
Y cuando se combina con polimorfismo, este enfoque es generalmente un éxito rotundo.
3. La default
implementación de métodos de interfaz.
Las clases abstractas pueden tener variables e implementaciones de métodos, pero no pueden tener herencia múltiple. Las interfaces no pueden tener variables o implementaciones de métodos, pero sí pueden tener herencia múltiple.
La situación se expresa en el siguiente cuadro:
Habilidad/propiedad | Clases abstractas | Interfaces |
---|---|---|
Variables | ✔ | ✖ |
Implementación del método | ✔ | ✖ |
Herencia múltiple | ✖ | ✔ |
Entonces, algunos programadores realmente querían que las interfaces tuvieran la capacidad de tener implementaciones de métodos. Pero tener la capacidad de agregar una implementación de método no significa que siempre se agregará uno. Agrégalo si quieres. O si no lo haces, entonces no lo hagas.
Además, los problemas con la herencia múltiple se deben principalmente a las variables. En cualquier caso, eso es lo que decidieron e hicieron. A partir de JDK 8, Java introdujo la capacidad de agregar implementaciones de métodos a las interfaces.
Aquí hay una tabla actualizada (para JDK 8 y superior):
Habilidad/propiedad | Clases abstractas | Interfaces |
---|---|---|
Variables | ✔ | ✖ |
Implementación del método | ✔ | ✔ |
Herencia múltiple | ✖ | ✔ |
Ahora, tanto para las clases abstractas como para las interfaces, puede declarar métodos con o sin implementación. ¡Y esta es una excelente noticia!
En las clases abstractas, los métodos sin implementación deben estar precedidos por la abstract
palabra clave. No necesita agregar nada antes de los métodos con una implementación. En las interfaces, ocurre lo contrario. Si un método no tiene una implementación, entonces no se debe agregar nada. Pero si hay una implementación, entonces default
se debe agregar la palabra clave.
Para simplificar, presentamos esta información en la siguiente tabla:
Habilidad/propiedad | Clases abstractas | Interfaces |
---|---|---|
Métodos sin implementación | abstract |
– |
Métodos con una implementación | – | default |
Problema
El uso de interfaces que tienen métodos puede simplificar en gran medida las jerarquías de clases grandes. Por ejemplo, el resumen InputStream
y OutputStream
las clases se pueden declarar como interfaces. Esto nos permite usarlos mucho más a menudo y mucho más convenientemente.
Pero ya hay decenas de millones (¿billones?) de clases Java en el mundo. Y si comienza a cambiar las bibliotecas estándar, entonces podría romper algo. ¡Como todo! 😛
Para no romper accidentalmente los programas y bibliotecas existentes, se decidió que las implementaciones de métodos en las interfaces tendrían la precedencia de herencia más baja .
Por ejemplo, si una interfaz hereda otra interfaz que tiene un método, y la primera interfaz declara el mismo método pero sin una implementación, la implementación del método de la interfaz heredada no llegará a la interfaz heredada. Ejemplo:
interface Pet
{
default void meow()
{
System.out.println("Meow");
}
}
interface Cat extends Pet
{
void meow(); // Here we override the default implementation by omitting an implementation
}
class Tom implements Cat
{
}
El código no se compilará porque la Tom
clase no implementa el meow()
método.
GO TO FULL VERSION