Una de las razones
para utilizar tuplas, es porque podemos procesar un conjunto de
elementos de distinto tipo, todos juntos. Esto es común cuando
utilizamos el método zip:
val symbols =
Array("<", "-", ">")
val counts =
Array(2, 10, 2)
val pairs =
symbols.zip(counts)
y esto retornara
pares de la siguiente forma:
Array(("<",
2), ("-", 10), (">", 2))
Luego estos pares se
pueden procesar juntos:
for ((s, n) <-
pairs) Console.print(s * n) // Prints <<---------->>
Algo que podemos
hacer es luego pasar este par a un mapa con el método toMap :
keys.zip(values).toMap
Clases
Es hora de hablar de
clases, para el que no esta muy interiorizado con la programación
orientada a objetos, le recomiendo que lea algo de teoría de objetos
antes de seguir.
Scala cuenta con una
estructura para definir clases como java o c++. Pero un tanto más
moderna y nos simplifica bastante las escritura.
class Counter {
private var
value = 0 // Se deben inicializar los valores
def
increment() { value += 1 } // Métodos por defecto son públicos
def current()
= value
}
En Scala no es
necesario indicar que una clase es publicas. Un archivo puede
contener muchas clases y estas son todas publicas.
Si queremos utilizar
la clase declarada lo podemos hacer:
val myCounter = new
Counter // o new Counter()
myCounter.increment()
println(myCounter.current)
Se pueden llamar los
métodos sin parámetros con paréntesis o sin paréntesis:
myCounter.current //
OK
myCounter.current()
// también esta bien
Cual es la mejor
forma? Por conversión se indica que se utilicen los paréntesis
cuando el método modifica un valor, si es un simple método para
acceder a un valor no es necesario. Como lo usamos anteriormente:
myCounter.increment()
//modifica el valor
println(myCounter.current)
// solo accede
Se puede forzar a no
utilizar parentesis en los metodos de la siguiente manera:
class Counter {
…
def current = value
// El metodo no es definido con ()
}
Ahora el método
current debe ser usado sin parentesis
Propiedades
getter y setters
En Java necesitamos
declarar métodos que nos permitan acceder a nuestros atributos
privados:
public class Person
{ // Esto es Java
private int age =
0;
public int getAge()
{ return age; }
public void
setAge(int age) { this.age = age; }
}
Porque es mejor esto
que hacer publico age? Porque podemos indicar restricciones, por
ejemplo si no queremos que la persona pueda ser más joven:
public void
setAge(int newValue) { if (newValue > age) age = newValue; }
Como se puede ver es
mucho mejor usar métodos getters y setters que hacer públicos los
atributos de una clase.
Scala provee métodos
getters y setters para los campos, aquí podemos ver una definición
de un campo publico:
class Person {
var age = 0
}
Scala genera una
clase para la JVM con un atributo privado y métodos getter y setter
públicos, si declaramos este atributo privado va a generar métodos
getter y setter privados.
En scala los métodos
son llamados age y age_= , de esta manera si hacemos:
println(fred.age) //
Llama al metodo fred.age()
fred.age = 21 //
Llama al metodo fred.age_=(21)
Esto es mucho mejor
que tener atributos privados, porque podemos redefinir estos métodos:
class Person {
private var
privateAge = 0 // hacemos privado a la edad y la renombramos.
def age = privateAge
def age_=(newValue:
Int) {
if (newValue
> privateAge) privateAge = newValue; // No puede ser más joven
}
Ahora podemos seguir
accediendo a age pero no podemos rejuvenecer a una persona:
val fred = new
Person
fred.age = 30
fred.age = 21
println(fred.age) //
30
Notemos que en Scala
no tenemos la necesidad de saber si estamos accediendo a un método o
a un atributo, de esta forma scala puede implementar este mecanismo.
Si esperamos tener
una propiedad solo lectura, es decir que no se pueda modificar
podemos utilizar la palabra val al declarar este atributo:
class Message {
val timeStamp = new
java.util.Date
…
}
Como ya vimos
anteriormente, en ciertos casos es necesario mantener un atributo que
no sea modificable directamente:
class Counter {
private var
value = 0 // Se deben inicializar los valores
def
increment() { value += 1 } // Métodos por defecto son públicos
def current =
value
}