Implement methods to safely retrieve and modify private data while maintaining integrity.
Imagine a bank where anyone could walk in and rewrite their account balance with a pencil. Without controlled access, your code is just as vulnerable—how do you stop a user from setting their age to -500 or their bank balance to 'infinity'?
In Object-Oriented Programming, we use the private modifier to hide data from the outside world. This is called Encapsulation. If a variable is public, any part of the program can change it to an invalid state. By making a variable private, we create a 'black box' where the internal data is protected. However, we still need a way to interact with that data safely. This is where Accessors (Getters) and Mutators (Setters) come in. They act as the official interface for your object, ensuring that no one touches the 'raw' data without permission.
Quick Check
What is the primary goal of making a class member 'private'?
Answer
To protect the data from being accessed or modified directly by external code, ensuring encapsulation.
A Getter is a method that returns the value of a private variable. It usually follows the naming convention `getVariableName()`. A Setter is a method that updates the value, usually named `setVariableName(newValue)`. Why use these instead of direct access? Because it gives the class control. A getter can format the data before returning it, and a setter can check if the new data is valid before saving it. This prevents the object from entering an 'illegal' state.
1. Define a private variable: `private String name;` 2. Create a Getter: `public String getName() { return name; }` 3. Create a Setter: `public void setName(String newName) { this.name = newName; }` 4. Now, external code must call `obj.setName("Alice")` instead of `obj.name = "Alice"`.
The true power of a setter is validation. Before assigning a value to a private field, we can use `if` statements to check if the data makes sense. For example, if we are setting a 'probability' value , we know that mathematically . If a user tries to set , the setter can reject the change or throw an error. This ensures that the object's internal state always follows the rules of the logic it represents.
Suppose we have a `Thermometer` class. We cannot have a temperature below absolute zero, which is approximately degrees Celsius.
1. `private double celsius;` 2. In the setter: `public void setCelsius(double temp) {` ` if (temp >= -273.15) {` ` this.celsius = temp;` ` } else {` ` System.out.println("Error: Temperature below absolute zero!");` ` }` `}`
Quick Check
If a class has a Getter but NO Setter for a specific variable, what kind of property is it?
Answer
A read-only property.
Sometimes, getters and setters don't just map to a single variable. They can perform calculations. For instance, a `Circle` class might have a private `radius`. You could create a `getArea()` method that calculates on the fly. Furthermore, you can create a `setArea()` method that actually updates the `radius` by calculating . This keeps your data synchronized and prevents redundant variables that might get out of sync.
Create a class where changing the area automatically updates the side length.
1. `private double side;` 2. `public double getArea() { return side * side; }` 3. `public void setArea(double area) {` ` if (area >= 0) {` ` this.side = Math.sqrt(area);` ` }` `}` 4. If a user calls `setArea(16.0)`, the `side` variable is automatically updated to .
Which of the following is a benefit of using a Setter instead of a public field?
In a class representing a Person, you want the 'age' to never be negative. Where should this logic go?
A class can have a getter for a variable without having a corresponding setter.
Review Tomorrow
In 24 hours, try to explain to a peer why a 'private' variable with a 'public' setter is safer than just making the variable 'public'.
Practice Activity
Create a 'SmartLight' class with a private 'brightness' level. Write a setter that ensures the brightness stays between and percent.