Original link
Problem
You want to control the visibility of fields is used as constructor parameters in a Scala class.
Solution
As shown in the following examples, the visibility of constructor fields in a Scala class are controlled by whether the Fie LDS is declared as val
, var
without either val
or var
, and whether was private
also added to the fields.
Here's the short version of the solution:
If A field is declared as a var
, the Scala generates both getter and setter methods for that field.
If The field is a val
, Scala generates only a getter method for it.
If a field doesn ' t has a var
or val
modifier, Scala gets conservative, and doesn ' t generate a getter or setter method For the field.
Additionally, and fields var
val
can is modified private
with the keyword, which prevents getters and setters from being Generated.
See the examples-follow for more details.
VAR fields
If A constructor parameter is declared as a var
, the value of the field can being changed, so Scala generates Both getter and setter methods for that field. In the following examples, the constructor parameter are name
declared as a var
, so the field can be accessed and mutate D:
class Person (var name:string) val p = new Person ("Alvin Alexander") P.name p.name = "Fred Flintstone" p.nameres1:string = Fred Flintstone
As shown, Scala does not follow the JavaBean naming convention when generating accessor and mutator methods.
Val Fields
If A constructor field is defined as a val
, the value of the field can ' t be changed once it ' s been set; it ' S immutable (like in final
Java). Therefore It makes sense that it should has an accessor method, and should not has a mutator method:
class Person (Val name:string) val p = new Person ("Alvin Alexander") P.name p.name = "Fred Flintstone"<console>:11:error:reassignment to val p.name = "Fred Flintstone" ^
The last example fails because a mutator method isn't generated for a val
field.
Fields without Val or var
When neither val
nor var
is specified on constructor parameters, the visibility of the field becomes very restricted, and Scala doesn ' t generate accessor or Mutator methods:
class Person (name:string) val p = new Person ("Alvin Alexander") p.name<console>:12:error:value name is not a member of person p.name ^
Adding private to Val or Var
In addition to these three basic configurations, you can add the private
keyword to a val
or var
field. This keyword prevents getter and setter methods from being generated, so the field can only is accessed from within member S of the class:
class person (private Var name:string) {def getName {println (name)} }val p = new Person ("Alvin Alexander ")p.name<console>:10:error:variable name in class person cannot is accessed in person p.name
p.getnameAlvin Alexander
Attempting to access p.name
fails because a getter method isn't generated name
for the field, so callers can ' t access it directly, but p.getName
works because it can access the name
field.
Discussion
If this was a little confusing, it helps to think about the choices the compiler had when generating code for you. When a field was defined as a val
, by definition of its value can ' t being changed, so it makes sense to generate a getter, but No setter. By definition, the value of a var
field can is changed, so generating both a getter and setter make sense F Or it.
The private
setting on a constructor parameter gives you additional flexibility. When it's added val
to a or var
field, the getter and setter methods is generated as before, but they ' re marked private
. (I rarely use this feature, but it's there if you need it.)
The accessors and mutators that is generated for your based on these settings is summarized in Table 4-1.
Table 4-1. The effect of constructor parameter settings
Visibility |
Accessor? |
Mutator? |
var
|
Yes |
Yes |
val
|
Yes |
No |
Default Visibility (no var or val ) |
No |
No |
Adding the private keyword to var orval |
No |
No |
You can also manually add your own accessor and mutator methods. See Recipe 4.6, for more information.
Case classes
Parameters in the constructor of a case class differ from these rules in one. Case class constructor parameters is by val
default. So if you define a case class field without adding val
or var
, like this:
case
class
Person
(
name
:
String
)
You can still access the field, just as if it were defined as a val
:
val p = person ("Dale Cooper") p.nameres0:string = Dale Cooper
Although this is slightly different than a "regular" class, it's a nice convenience and have to does with the the-the-case classe S is intended to being used in functional programming, i.e., as immutable records. See Recipe 4.14, for more information on how case classes work.
Controlling the Visibility of Constructor fields