Scala Meetup Montevideo Message Board › Método o atributos públicos?

Método o atributos públicos?

A former member
Post #: 2
Estaba leyendo el capitulo 6 del libro de Odersky, el ejemplo de los Rationals.

class Rationals (n : Int, d : Int)

OK, por defecto n y d son definidos como val. Además, se crea la clase con dos atributos privados, de nombres n y d. O sea, me crea el objeto pero no puedo acceder a los valores de los atributos.

Ahora, si creo 'variables' de instancia (fields) explícitamente

class Rationals (n : Int, d : Int) {
val n1=n
val d1=d
}

voy a poder acceder a los atributos:

val a = new Rationals(2,3)
println(a.n1)

Mi pregunta es: ¿ a.n1 es una función del mismo nombre del atributo o un método, i.e. una función con el mismo nombre de ese atributo?

Leí que los valores definidos en una clase, por defecto son public y no private, por lo que n1 y d1 serían públicos, pero me rechina un poco que se accedan valores directamente, no se por qué me suena 'herético'. Lo corrí en la Scala worksheet pero no me doy cuenta si estoy frente a una función o a un val.

Gracias por leer hasta acá! :-)
Diego V.
user 37598312
Sydney, AU
Post #: 1
Al ser vals, dado el objeto nunca lo vas a poder modificar, por lo que la ausencia de getters y setters tiene sentido en este caso. si tenes una instancia de Rational, no tiene sentido que lo estés modificando internamente.

Scala tiene transparencia referencial en sus propiedades, lo que significa que para alguien que consume el objeto le da igual que lo que llame en él (n o d) sea una propiedad o un método. Podés hasta hacer un override de un val con un def y viceverse cuando usás herencia, para que te des cuenta del alcance del tema. Internamente Scala representa un val con un getter y setter típico, y te permite si querés especificar el setter de la propiedad, pero como en el 90% de los casos no es necesario se utiliza el shorthand de "val" por defecto.

Extra: podés simplificar la definición de la clase asi:
class Rational(val n: Int, d: Int)
o incluso cuando llegues a case classes en el libro:
case class Rational(n: Int, d: Int)
Federico S.
fedesilva
Group Organizer
Montevideo, UY
Post #: 1
Como dice Diego mas abajo lo mejor es declarar la clase así:

class Rationals( val n: Int, val d: Int)

con eso ya tenés los vals declarados y no necesitas un valor intermedio para el argumento.

Por otro lado si fueran vars (que también pueden ser declarados como argumentos directamente) te crea un par de accesors y hace que se vean como acceso a vars.

def d1_=(i:Int) { ... }
def d1 = ...

y al usarlo el compilador reescribe las llamadas correctas.

Acá para terminar hago dos notas:

1) Declará vals y listo y accedelas directamente y no te preocupes. No hay tal herejía.
Herejía es declarar los getters y los setters para proveer una indirección que no hace nada.

2) Esto de la generación de los accesors por parte de el compilador se llama "Uniform Access Principle"
no transparencia referencial.
Transparencia referencial quiere decir que dos llamadas con los mismos parámetros producen el mismo resultado
y ese no es el caso cuando usamos vars. Si le asigno un valor y consulto y luego reasigno, la consulta cambia
el valor de retorno.

Abrazos y los veo en la próxima!

Ah!, me olvidé en la reunión pasada de comentarles que nos hablamos por un google group que armó Pablo Zebraitis hace algún tiempo.

https://groups.google...­

son bienvenidos!






A former member
Post #: 3
Diego, Federico:

Gracias por sus respuestas! Aprendí montones leyéndolos.

Abrazo,
Marcelo
A former member
Post #: 4
Un link que me ayudó a entender lo del Uniform Access Principle: http://joelabrahamsso...­

Lo más interesante, por lo menos para un principiante como yo, es la idea de compilar Scala y decompilar las clases Java a ver que tienen adentro, o sea, como Scala implementa las cosas.

class Rationals (n : Int, d : Int) {
val n1=n
val d1=d
}

esto (bueno, lo hice dentro de un objeto aaa) genera el codigo en Java:

public class aaa$$anonfun$main$1$Rationals$1
implements ScalaObject
{
private final int n1;
private final int d1;
public final aaa..anonfun.main.1 $outer;

public int n1()
{
return this.n1; }
public int d1() { return this.d1; }
...

O sea, atributos privados (final por lo de val) con getters con igual nombre.

Por otra parte:

class Rationals2 (var n : Int, var d : Int)

genera

public class aaa$$anonfun$main$1$Rationals2$1
implements ScalaObject
{
private int n;
private int d;
public final aaa..anonfun.main.1 $outer;

public int n()
{
return this.n; }
public void n_$eq(int paramInt) { this.n = paramInt; }
public int d() { return this.d; }
public void d_$eq(int paramInt) { this.d = paramInt; }
...

O sea, lo que decía Federico, los setters n_= y d_=

Je, ta, ahora me quedo tranquilo. ;-)

Abrazo!
Diego V.
user 37598312
Sydney, AU
Post #: 2
Gracias Fede, me confundí de terminología, mis disculpas :)
Federico S.
fedesilva
Group Organizer
Montevideo, UY
Post #: 2
un pequeño desliz! :D
Powered by mvnForum

Our Sponsors

  • Pyxis

    Pyxis pone el lugar para reunirnos.

  • aqua it

    Aqua.it nos invita con las pizzas y financia otros gastos del grupo.

  • Guruhub

    Guruhub nos invita con los refrescos y financia otros gastos del grupo.

People in this
Meetup are also in:

Sign up

Meetup members, Log in

By clicking "Sign up" or "Sign up using Facebook", you confirm that you accept our Terms of Service & Privacy Policy