2010-11-26 5 views

Respuesta

14

En primer lugar, esto permite intercambiar una var/val pública con un (par de) def (s) y aún mantener la compatibilidad binaria. En segundo lugar, permite anular una var/val en las clases derivadas.

10

Primero, mantener el campo público permite que un cliente lea y escriba el campo. Como es beneficioso tener objetos inmutables, recomendaría que el campo sea de solo lectura (lo que puedes lograr en Scala declarándolo como "val" en lugar de "var").

Ahora volvemos a su pregunta real. Scala le permite definir sus propios setters y getters si necesita más que las versiones triviales. Esto es útil para mantener invariantes. Para los instaladores, es posible que desee comprobar el valor en el que está establecido el campo. Si mantiene el campo público, no tiene posibilidad de hacerlo.

Esto también es útil para los campos declarados como "val". Supongamos que tiene un campo de tipo Array [X] para representar el estado interno de su clase. Un cliente ahora podría obtener una referencia a esta matriz y modificarla. De nuevo, no tiene posibilidad de garantizar que se mantenga la invariante. Pero dado que puede definir su propio getter, puede devolver una copia de la matriz real.

El mismo argumento se aplica cuando crea un campo de un tipo de referencia "público final" en Java: los clientes no pueden restablecer la referencia pero aún modificar el objeto al que apunta la referencia.

En una nota relacionada: acceder a un campo a través de captadores en Scala parece acceder al campo directamente. Lo bueno de esto es que permite hacer que acceder a un campo y llamar a un método sin parámetros en el objeto parezca lo mismo. Entonces, si decide que ya no quiere almacenar un valor en un campo, sino que lo calcula sobre la marcha, el cliente no tiene que preocuparse porque le parece lo mismo: esto se conoce como Uniform Access Principle

8

En resumen: el Principio de Acceso Uniforme.

Puede usar un valor val para implementar un método abstracto a partir de una superclase. Imagine la siguiente definición de algún paquete de gráficos imaginaria:

abstract class circle { 
    def bounds: Rectangle 
    def centre: Point 
    def radius: Double 
} 

Hay dos subclases posibles, uno donde el círculo se define en términos de un cuadro delimitador, y uno donde se define en términos del centro y el radio. Gracias a UAP, los detalles de la implementación se pueden abstraer por completo y cambiar fácilmente.

También hay una tercera posibilidad: lazy vals. Estos serían muy útiles para evitar volver a calcular los límites de nuestro círculo una y otra vez, pero es difícil imaginar cómo vagos se podrían implementar sin el principio de acceso uniforme.