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?
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.
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.
To access the private members of the superclass you need to use setter and getter methods and call them using the subclass object.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With