Utilizar un Interface como un Tipo

Como se mencioó anteriormente, cuando se define un nuevo interface, en esencia se está definiendo un tipo de referencia. Se pueden utilizar los nombres de interface en cualquier lugar donde se usaría un nombre de dato de tipos primitivos o un nombre de datos del tipo de referencia.

Por ejemplo, supongamos que se ha escrito un programa de hoja de cálculo que contiene un conjunto tabular de celdas y cada una contiene un valor. Querríamos poder poner cadenas, fechas, enteros, ecuaciones, en cada una de las celdas de la hoja. Para hacer esto, las cadenas, las fechas, los enteros y las ecuaciones tienen que implementar el mismo conjunto de métodos. Una forma de conseguir esto es encontrar el ancestro común de las clases e implementar ahí los métodos necesarios. Sin embargo, esto no es una solución práctica porque el ancestro común más frecuente es Object. De hecho, los objetos que puede poner en las celdas de su hoja de cálculo no están relacionadas entre sí, sólo por la clase Object. Pero no puede modificar Object.

Una aproximación podría ser escribir una clase llamada ValordeCelda que representara los valores que pudiera contener una celda de la hoja de cálculo. Entonces se podrían crear distintas subclases de ValordeCelda para las cadenas, los enteros o las ecuaciones. Además de ser mucho trabajo, esta aproximación arbitraria fuerza una relación entre esas clases que de otra forma no sería necesaria, y debería duplicar e implementar de nuevo clases que ya existen.

Se podría definir un interface llamado CellAble que se parecería a esto:

interface CellAble {
    void draw();
    void toString();
    void toFloat();
}
Ahora, supongamos que existen objetos Línea y Columna que contienen un conjunto de objetos que implementan el interface CellAble. El método setObjectAt() de la clase Línea se podría parecer a esto:
class Línea {
    private CellAble[] contents;
    . . .
    void setObjectAt(CellAble ca, int index) {
        . . .
    }
    . . .
}
Observa el uso del nombre del interface en la declaración de la variable miembro contents y en la declaración del argumento ca del método. Cualquier objeto que implemente el interface CellAble, sin importar que exista o no en el árbol de clases, puede estar contenido en el array contents y podría ser pasado al método setObjectAt().


Ozito