top of page

8 Genéricos

 


La última característica de Scala que vamos a explorar en este tutorial es la generalidad. Los programadores Java veteranos conocen los problemas causados por la falta de la existencia de genéricos en su lenguaje, un defecto corregido en Java 1.5.


La generalidad es la habilidad de escribir código parametrizado por tipos. Por ejemplo, un programador que escriba una librería para listas ordenadas se encuentra con el problema de decidir qué tipo dar a los elementos de la lista. Puesto que esta lista se puede utilizar en contextos muy diversos, no es posible decidir si el tipo de datos de los elementos tiene que ser, por ejemplo, int. Eso sería completamente arbitrario y excesivamente restrictivo.


Los programadores Java recurrían al uso de Object, que es el super-tipo de todos los objetos. Pero esta solución está lejos de ser ideal puesto que no vale para los tipos básicos(int, long, float, etc.) e hace que el programador tenga que introducir múltiples conversiones dinámicas de tipos.


Scala posibilita definir clases(y métodos) genéricos para solucionar ese problema. Veamoslo con un ejemplo de la clase contendor más sencilla posible: una referencia, que puede ser vacía o apuntar a un objeto de algún tipo.


class Reference[a] {
    private var contents: a = _
    def set(value: a) { contents = value }
    def get: a = contents
}

 


Esta clase Reference está parametrizada por un tipo de dato, llamado a, que es el tipo de sus elementos. Este tipo se utiliza en el cuerpo de la clase como el tipo de la variable contents, del argumento del método set, y del tipo de respuesta del método get.


El ejemplo anterior de código nos presenta las variables en Scala, que no requieren mayor explicación. Aun así es interesante observar que el valor con el que inicializamos la variable es _, que representa un valor por defecto. Este valor es 0 para los tipos numéricos, false para el tipo booleano,() para el tipo unit, y null para todos los tipos de objetos.

 

Para utilizar esta clase Reference, se ha de especificar que tipo usar para el parámetro a, el que será el tipo del elemento contenido en la referencia. Por ejemplo, para crear y usar un celda que guarde un entero, se podría escribir lo siguiente:

 

object ReferenciaEntera {
    def main(args: Array[String]) {
        val celda = new Reference[Int]
        celda.set(33)
        println("La referencia contiene la mitad de " + (cell.get * 2))
    }

}

 

 

Como se puede ver en el ejemplo, no es necesario convertir el tipo del valor devuelto por el método get antes de usarlo como un entero. Y tampoco se puede almacenar nada que no sea un entero en esa celda particular puesto que ha sido declarada como contenedora de un entero.

bottom of page