Protect your data by controlling access to class members using visibility levels.
Imagine a bank where every customer can walk into the vault and rewrite their own balance with a Sharpie. Without data hiding, your code is just as vulnerable.
Encapsulation is the practice of bundling data (variables) and the methods that act on that data into a single unit called a class. Think of it as a 'black box.' You don't need to know how the internal gears of a watch turn to tell the time; you only need the interface (the hands and the crown). In programming, we hide the internal state of an object and only allow interaction through a strictly defined interface. This prevents 'outside' code from accidentally corrupting the internal logic, ensuring that the object remains in a valid state. If an object has variables, encapsulation ensures that all are modified only under controlled conditions.
Quick Check
In your own words, why is it dangerous for external code to modify an object's internal variables directly?
Answer
Direct modification can bypass validation logic, leading to 'invalid states' or corrupted data that the object wasn't designed to handle.
To implement encapsulation, we use Access Modifiers. These keywords define the 'visibility' of class members. There are three primary levels: 1. Public: The member is accessible from any other class. 2. Private: The member is accessible only within the class it is defined. This is the gold standard for data hiding. 3. Protected: The member is accessible within its own class and by subclasses (inheritance).
By default, you should follow the Principle of Least Privilege: keep everything `private` unless you have a specific reason to make it otherwise. This reduces the 'surface area' for bugs.
Let's look at a basic implementation of a User class: 1. Define a class `User`. 2. Set the `password` variable to `private` so it cannot be read from outside. 3. Set the `username` to `public` (or use a getter).
```java public class User { public String username; private String password; // Hidden from the world!
public void login(String attempt) { if(attempt.equals(password)) { / logic / } } }```
If data is `private`, how do we use it? We use Accessor (getter) and Mutator (setter) methods. These act as security guards. Instead of allowing , we call `setX(10)`. Inside `setX`, we can add logic: `if (value > 0) { x = value; }`. This ensures the invariant (a condition that must always be true) of our class is never broken. For a circle, the invariant might be . If we expose the radius directly, someone could set it to , breaking the geometry logic of our program.
Consider a `BankAccount` class where we must prevent negative balances. 1. Create a `private double balance`. 2. Create a `public void deposit(double amount)`. 3. Inside the method, check: `if (amount > 0) { balance += amount; }`.
This ensures that the balance can only increase through valid transactions, maintaining the integrity of the financial data.
Quick Check
Which access modifier allows a child class to see a parent's variable, but keeps it hidden from the rest of the program?
Answer
The 'protected' modifier.
When we expose internal data, we create tight coupling. If other classes depend on the specific name or type of a public variable, you can never change that variable without breaking the entire system. This is a 'leaky abstraction.' Furthermore, direct access causes side effects: changes in one part of the code that cause unexpected behavior elsewhere. By using encapsulation, we achieve modularity. We can change the internal math of a class—for example, switching from calculating area as to a more complex integral—without the rest of the program ever knowing or needing to change.
Imagine a `Thermostat` class. 1. It has a `private double temperature`. 2. It has a `public void setTemp(double t)`. 3. The challenge: The hardware can only handle changes of degrees per minute to prevent the heater from exploding. 4. Implementation: The `setTemp` method calculates . If , it rejects the change.
If `temperature` were `public`, a rogue script could set it from to instantly, bypassing the safety check.
Which modifier provides the highest level of data protection?
What is a 'setter' method primarily used for?
Encapsulation makes it easier to change the internal implementation of a class without affecting other parts of the program.
Review Tomorrow
In 24 hours, try to explain the 'Principle of Least Privilege' and list the three main access modifiers from most restrictive to least restrictive.
Practice Activity
Create a 'Student' class with a private 'grade' variable. Write a setter that only accepts values between and .