Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access and mutate private field in scala?

Tags:

scala

I have something like:

class Address(private var street:String, private var city: String, private var postCode: String) extends Model

When I try to do:

address = new Address(....)
address.city = "changed"

I get compile error. So what is the solution? Note that the fields must remain private.

Also is there a shortcut syntax than having to repeat the keyword private when all fields in the class are private?

like image 500
ace Avatar asked Jun 27 '11 19:06

ace


People also ask

How do you access private classes in Scala?

In Scala, a private top-level class is also accessible from nested packages. This makes sense, since the enclosing scope of both the private class and the nested package is the same (it's the package inside which both are defined), and private means that the class is accessible from anywhere within its enclosing scope.

How do I access a private field?

If we want to access Private Field and method using Reflection we just need to call setAccessible(true) on the field or method object which you want to access. Class. getDeclaredField(String fieldName) or Class. getDeclaredFields() can be used to get private fields.

How do you access a private field in superclass?

To access the private members of the superclass you need to use setter and getter methods and call them using the subclass object.

Can private variables be used in subclasses?

Can you access a private variable from the superclass using the super keyword within the subclass? No. Private variables are only accessible to the class members where it belongs.


2 Answers

There seems to be a fundamental misunderstanding here. All fields in Scala are private. It's not just a default nor is it optional.

For example, let's say you have this:

class Address(var street: String)

The field where street is stored is private. Say you do this:

val x = new Address("Downing")
println(x.street)

This code does not directly access the private field for street. x.street is a getter method.

Say you do this:

x.street = "Boulevard"

This code does not directly modify the private field for street. x.street = is actually the method x.street_=, which is a setter method.

You can't directly access fields in Scala. Everything is done through getters and setters. In Scala, every field is private, every field has getters, and every var has setters.

like image 155
Daniel C. Sobral Avatar answered Oct 31 '22 11:10

Daniel C. Sobral


You can define accessors and mutators like this:

class Address(private var _street: String, private var _city: String, private var _postCode: String){
  def street = _street
  def street_=(street: String) = _street = street

  def city = _city
  def city_=(city: String) = _city = city

  def postCode = _postCode
  def postCode_=(postCode: String) = _postCode = postCode
}

The need to rename the fields (which might clash with named parameters) and that the constructor ignores the mutator when instantiating the class is a known problem, but no efforts are currently made to improve the situation.

like image 21
soc Avatar answered Oct 31 '22 12:10

soc