Interfaz de Java

Una interfaz (en inglés: Interface), en el lenguaje de programación JAVA, es un tipo abstracto y una colección de métodos abstractos. Las interfaces normalmente se declaran con `interface`. Una clase hereda los métodos abstractos de la interfaz mediante la implementación de la interfaz.

Una interfaz no es una clase; la forma de escribir una interfaz es muy similar a la de una clase, pero pertenecen a conceptos diferentes. Una clase describe los atributos y métodos de los objetos. Una interfaz, en cambio, contiene los métodos que una clase debe implementar.

A menos que la clase que implementa la interfaz sea una clase abstracta, dicha clase debe definir todos los métodos de la interfaz.

Las interfaces no se pueden instanciar, pero sí se pueden implementar. Una clase que implementa una interfaz debe implementar todos los métodos descritos en ella; de lo contrario, debe declararse como clase abstracta. Además, en Java, un tipo de interfaz se puede utilizar para declarar una variable; estas variables pueden ser un puntero nulo o estar vinculadas a un objeto que implementa dicha interfaz.

Similitudes entre interfaces y clases:

  • Una interfaz puede tener múltiples métodos.
  • El archivo de la interfaz se guarda en un archivo con extensión `.java`, y el nombre del archivo utiliza el nombre de la interfaz.
  • El archivo de bytecode de la interfaz se guarda en un archivo que finaliza en `.class`.
  • El archivo de bytecode correspondiente a la interfaz debe estar en una estructura de directorios que coincida con el nombre del paquete.

Diferencias entre interfaces y clases:

  • Las interfaces no se pueden utilizar para instanciar objetos.
  • Las interfaces no tienen métodos constructores.
  • Todos los métodos de una interfaz deben ser métodos abstractos. Después de Java 8, las interfaces pueden tener métodos no abstractos modificados con la palabra clave `default`.
  • Las interfaces no pueden contener variables miembro, excepto variables `static` y `final`.
  • La interfaz no es heredada por la clase, sino que debe ser implementada por la clase.
  • Las interfaces admiten herencia múltiple.

Características de las interfaces

  • Cada método de una interfaz también es implícitamente abstracto; los métodos de la interfaz se especifican implícitamente comopublic abstract(solo pueden ser `public abstract`; cualquier otro modificador provocará un error).
  • Las interfaces pueden contener variables, pero las variables de la interfaz se especifican implícitamente comopublic static finalvariables (y solo pueden ser `public`; si se modifican con `private` se producirá un error de compilación).
  • Los métodos de una interfaz no pueden implementarse dentro de la interfaz; solo pueden ser implementados por las clases que implementan la interfaz.

Diferencias entre clases abstractas e interfaces

  • 1. Los métodos de una clase abstracta pueden tener un cuerpo de método, es decir, pueden implementar la funcionalidad concreta del método, pero los métodos de una interfaz no.
  • 2. Las variables miembro de una clase abstracta pueden ser de varios tipos, mientras que las variables miembro de una interfaz solo pueden serpublic static finalde tipo.
  • 3. Las interfaces no pueden contener bloques de código estáticos ni métodos estáticos (métodos modificados con `static`), mientras que las clases abstractas sí pueden tener bloques de código estáticos y métodos estáticos.
  • 4. Una clase solo puede heredar de una clase abstracta, pero una clase puede implementar múltiples interfaces.

Nota.Nota: Después de JDK 1.8, las interfaces pueden tener métodos estáticos y cuerpos de método.

Nota.Nota: Después de JDK 1.8, las interfaces permiten incluir métodos con implementación concreta, llamados "métodos predeterminados". Los métodos predeterminados se modifican con la palabra clave `default`. Para más contenido, consulteMétodos predeterminados de Java 8。

Nota.Nota: Después de JDK 1.9, se permite definir métodos como `private`, de modo que cierto código reutilizable no exponga los métodos. Para más contenido, consulteMétodos privados de interfaz en Java 9。


Declaración de interfaces

La sintaxis de declaración de una interfaz es la siguiente:

[Visibilidad] interfaceNombre de la interfaz[extendsOtros nombres de interfaz] { //Declaración de variables //Métodos abstractos }

La palabra clave `interface` se utiliza para declarar una interfaz. A continuación se muestra un ejemplo sencillo de declaración de una interfaz.

Código del archivo NameOfInterface.java:

/*Nombre del archivo: NameOfInterface.java*/ import java.lang.*; //Importar paquete public interface NameOfInterface { //Campos `final`, `static` de cualquier tipo //Métodos abstractos }
Las interfaces tienen las siguientes características:
  • Las interfaces son implícitamente abstractas; al declarar una interfaz, no es necesario usarabstractla palabra clave.
  • Cada método en una interfaz también es implícitamente abstracto; al declararlo, tampoco es necesario usarabstractla palabra clave.
  • Todos los métodos en una interfaz son públicos.

Ejemplo

Código del archivo Animal.java:

/*Nombre del archivo: Animal.java*/ interface Animal { public void eat(); public void travel(); }

Implementación de interfaces

Cuando una clase implementa una interfaz, debe implementar todos los métodos de la interfaz. De lo contrario, la clase debe declararse como clase abstracta.

Una clase utiliza la palabra clave `implements` para implementar una interfaz. En la declaración de la clase, la palabra clave `implements` se coloca después de la declaración de `class`.

La sintaxis para implementar una interfaz puede usar esta fórmula:

Sintaxis de la interfaz:

...implementsNombre de la interfaz[, otros nombres de interfaz, otros nombres de interfaz..., ...] ...

Ejemplo

Código del archivo MammalInt.java:

/*Nombre del archivo: MammalInt.java*/ public class MammalInt implements Animal{ public void eat(){ System.out.println("Mammal eats"); } public void travel(){ System.out.println("Mammal travels"); } public int noOfLegs(){ return 0; } public static void main(String args[]){ MammalInt m = new MammalInt(); m.eat(); m.travel(); } }

El resultado de compilar y ejecutar el ejemplo anterior es el siguiente:

Mammal eats
Mammal travels

Al sobrescribir los métodos declarados en una interfaz, se deben tener en cuenta las siguientes reglas:

  • Cuando una clase implementa los métodos de una interfaz, no puede lanzar excepciones comprobadas; solo puede lanzar dichas excepciones comprobadas en la interfaz o en la clase abstracta que hereda la interfaz.
  • Cuando una clase sobrescribe un método, debe mantener el mismo nombre de método y debe conservar el mismo tipo de retorno o un tipo de retorno compatible.
  • Si la clase que implementa la interfaz es una clase abstracta, entonces no es necesario implementar los métodos de la interfaz.

Al implementar interfaces, también se deben tener en cuenta algunas reglas:

  • Una clase puede implementar múltiples interfaces al mismo tiempo.
  • Una clase solo puede heredar de una clase, pero puede implementar múltiples interfaces.
  • Una interfaz puede heredar de otra interfaz, lo cual es bastante similar a la herencia entre clases.

Herencia de interfaces

Una interfaz puede heredar de otra interfaz, de manera similar a la herencia entre clases. La herencia de interfaces utiliza la palabra clave `extends`; la subinterfaz hereda los métodos de la interfaz padre.

La siguiente interfaz `Sports` es heredada por las interfaces `Hockey` y `Football`:

//Nombre del archivo: Sports.java public interface Sports { public void setHomeTeam(String name); public void setVisitingTeam(String name); } //Nombre del archivo: Football.java public interface Football extends Sports { public void homeTeamScored(int points); public void visitingTeamScored(int points); public void endOfQuarter(int quarter); } //Nombre del archivo: Hockey.java public interface Hockey extends Sports { public void homeGoalScored(); public void visitingGoalScored(); public void endOfPeriod(int period); public void overtimePeriod(int ot); }

La interfaz `Hockey` declara cuatro métodos propios y hereda dos métodos de la interfaz `Sports`; de este modo, la clase que implementa la interfaz `Hockey` debe implementar seis métodos.

De manera similar, la clase que implementa la interfaz `Football` debe implementar cinco métodos, dos de los cuales provienen de la interfaz `Sports`.


Herencia múltiple de interfaces

En Java, la herencia múltiple de clases no es válida, pero las interfaces sí permiten la herencia múltiple.

En la herencia múltiple de interfaces, la palabra clave `extends` solo se usa una vez, seguida de las interfaces heredadas. Como se muestra a continuación:

public interface Hockey extends Sports, Event

El fragmento de programa anterior es una subinterfaz legalmente definida. A diferencia de las clases, las interfaces permiten la herencia múltiple, y `Sports` y `Event` pueden definir o heredar los mismos métodos.


Interfaz de marcado

La interfaz de marcado más común es aquella que no contiene ningún método.

Una interfaz de marcado es una interfaz sin métodos ni atributos. Simplemente indica que su clase pertenece a un tipo específico, para que otro código pueda comprobar y permitir hacer ciertas cosas.

Función de la interfaz de marcado: en términos simples y gráficos, es ponerle una etiqueta (un sello) a un objeto, haciendo que el objeto tenga uno o varios privilegios.

Por ejemplo: la interfaz `java.util.EventListener`, que es heredada por la interfaz `MouseListener` del paquete `java.awt.event`, se define de la siguiente manera:

package java.util; public interface EventListener {}

Una interfaz sin ningún método se denomina interfaz de marcado. Las interfaces de marcado se utilizan principalmente con los dos propósitos siguientes:

  • Establecer una interfaz padre común:

    Como la interfaz `EventListener`, que es una API de Java extendida por docenas de otras interfaces, se puede usar una interfaz de marcado para establecer una interfaz padre de un grupo de interfaces. Por ejemplo: cuando una interfaz hereda la interfaz `EventListener`, la máquina virtual de Java (JVM) sabe que dicha interfaz se utilizará en un esquema de delegación de eventos.

  • Añadir un tipo de datos a una clase:

    Este es el propósito original de las interfaces de marcado. Una clase que implementa una interfaz de marcado no necesita definir ningún método de la interfaz (porque la interfaz de marcado no tiene métodos en absoluto), pero la clase se convierte en un tipo de interfaz mediante polimorfismo.

Otras extensiones