Interfaces

Hemos visto que en Java solo es posible la herencia simple, el hecho de que una clase tan sólo puede heredar de otra clase, nunca de varias. La forma de simular una herencia múltiple la tenemos en el uso de interfaces. Una interface es una clase abstracta llevada al extremo. Una clase abstracta puede contener métodos implementados y métodos abstractos, así como propiedades y constructores. Pues bien, en una interface todos los métodos declarados son abstractos, nunca puede haber métodos implementados. Todos los métodos declarados en una interfaz son públicos (public) y abstractos (abstract), con independencia de que mencionemos estos modificadores en el código o no. Igualmente, todos los atributos son public, static y final. En otras palabras, sólo se pueden declarar atributos constantes.

Al igual que los nombres de clases abstractas, los nombres de interfaz se utilizan como tipos de variables de referencia. Imagine un grupo de objetos que comparten la misma habilidad: pueden volar. Puede construir una interfaz pública llamada ObjetoVolador que admite tres operaciones: despegar, aterrizar y volar.

Como podemos observar en el diagrama UML, las interfaces se marcan con el indicador <> en la sección de nombre. Por otro lado, utilizamos una flecha discontinua para indicar la clase que implementa una interface. A continuación vemos el código fuente de la interface y la clase.

Puede haber muchas clases que implementen la interfaz ObjetoVolador. Un Avion, un ave o Superman pueden volar.

 

Código ejemplo interfaces

 

MULTIPLES INTERFACES

Una clase puede implementar varias interfaces. El Hidroavion no sólo puede volar, sino también navegar. La clase Hidroavion amplía la clase Avion, con lo que hereda esa implementación de la interfaz ObjetoVolador. La clase Hidroavión tambiénimplementa la interfaz Nautico.

 

 

CUANDO UTILIZAR INTERFACES

Las interfaces se utilizan para:

    • Declarar métodos que serán implementados por una o varias clases.
    • Dar a conocer la interfaz de programación de un objeto sin revelar el  verdadero cuerpo de la clase (esto puede ser útil al distribuir un paquete de clases a otros desarrolladores).
    • Identificar las similitudes entre clases no relacionadas sin tener que establecer ninguna relación entre ellas.
    • Simular la herencia múltiple declarando una clase que implemente varias interfaces.

 

CLASES ABSTRACTAS VS INTERFACES

Es difícil, al principio, determinar cuándo es necesario, o conveniente, crear una interfaz o crear una clase abstracta. Primero recordemos que ambos artefactos tienen propósitos distintos. Las clases abstractas sirven para establecer una jerarquía de tipos y proveer un comportamiento básico. Las interfaces son definiciones de protocolos, determinan el comportamiento de un tipo. Segundo, las clases abstractas pueden incluir código, definir atributos, tener métodos estáticos, etc. En cambio, las interfaces son sólo declaraciones de mensajes.

Por este motivo las interfaces son mucho menos restrictivas que las clases abstractas, ya que no fuerzan nada más que lo necesario, solamente el protocolo. Por ejemplo, una clase abstracta podría definir un atributo de instancia, eso ya es una restricción de implementación,  ya que todas las subclases tienen como peso ese atributo (incluso si no lo usan). Además, la herencia es una clase que se puede utilizar una sola vez. Solo podemos heredar de una clase. Podemos implementar todas las interfaces necesarias. Nuestra clase, es entonces, polifacética.

Ya que puede servir a muchos más clientes. Generalmente, si nuestra clase abstracta solamente define métodos, lo mejor es crear una interfaz y reemplazarla. Así ganamos un poco de flexibilidad y dejamos la clase abstracta para cuando queremos reutilizar comportamiento (código) en común entre varias clases similares.

Una forma de saber cuándo debemos crear una interfaz es cuando estamos programando una clase y sabemos que vamos a necesitar ciertos colaboradores que todavía no existen. En ese caso es cuando podemos crear una interfaz. Así nuestra clase compilará habiendo ya creado los artefactos mínimos para eso.