5.2 Properties with Getters and Setters
When writing a Java class, we don’t like to use public fields:
public class Person { // This is Java public int age; // Frowned upon in Java }
With a public field, anyone could write to fred.age, making Fred younger or older. That’s why we prefer to use getter and setter methods:
public class Person { // This is Java private int age; public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
A getter/setter pair such as this one is often called a property. We say that the class Person has an age property.
Why is this any better? By itself, it isn’t. Anyone can call fred.setAge(21), keeping him forever twenty-one.
But if that becomes a problem, we can guard against it:
public void setAge(int newValue) { if (newValue > age) age = newValue; } // Can't get younger
Getters and setters are better than public fields because they let you start with simple get/set semantics and evolve them as needed.
Scala provides getter and setter methods for every field. Here, we define a public field:
class Person { var age = 0 }
Scala generates a class for the JVM with a private age field and getter and setter methods. These methods are public because we did not declare age as private. (For a private field, the getter and setter methods are private.)
In Scala, the getter and setter methods are called age and age_=. For example,
println(fred.age) // Calls the method fred.age()
fred.age = 21 // Calls fred.age_=(21)
In Scala, the getters and setters are not named getXxx and setXxx, but they fulfill the same purpose. Section 5.5, “Bean Properties,” on page 61 shows how to generate Java-style getXxx and setXxx methods, so that your Scala classes can interoperate with Java tools.
At any time, you can redefine the getter and setter methods yourself. For example,
class Person { private var privateAge = 0 // Make private and rename
def age = privateAge def age_=(newValue: Int) { if (newValue > privateAge) privateAge = newValue; // Can't get younger } }
The user of your class still accesses fred.age, but now Fred can’t get younger:
val fred = new Person
fred.age = 30
fred.age = 21
println(fred.age) // 30