Encapsulation

Encapsulation is one of the core features of OOP. This lesson covers how to protect object data.

What is Encapsulation

Encapsulation bundles data (attributes) and methods that operate on that data together, hiding internal implementation details.

Benefits of Encapsulation

Benefit Description
Data protection Prevents direct external access and modification
Flexibility Can add validation logic in setters
Maintainability Internal changes don't affect external calls

Access Modifiers

Java has four access modifiers that control the visibility of classes, attributes, and methods.

Modifier Same Class Same Package Subclass Different Package
public
protected
Default (no modifier)
private

Example: Access Modifiers

JAVA
public class Person {
    public String name;      // Public, accessible anywhere
    protected int age;       // Protected, accessible in same package and subclasses
    String address;          // Default, accessible in same package
    private double salary;   // Private, accessible only in this class
}
▶ Try it Yourself
💡 Recommendation: Use private for attributes and access them through getter/setter methods.

Getters and Setters

Why Getters/Setters are Needed

JAVA
public class Person {
    private String name;
    private int age;
    
    // Getter
    public String getName() {
        return name;
    }
    
    // Setter
    public void setName(String name) {
        this.name = name;
    }
    
    public int getAge() {
        return age;
    }
    
    public void setAge(int age) {
        // Add validation logic in setter
        if (age >= 0 && age <= 150) {
            this.age = age;
        } else {
            System.out.println("Invalid age");
        }
    }
}

Example: Using Getters/Setters

JAVA
public class PersonTest {
    public static void main(String[] args) {
        Person p = new Person();
        
        // Set values via setters
        p.setName("Alice");
        p.setAge(25);
        
        // Get values via getters
        System.out.println("Name: " + p.getName());
        System.out.println("Age: " + p.getAge());
        
        // Validation in setter
        p.setAge(-5);  // Output: Invalid age
    }
}
▶ Try it Yourself

JavaBean Conventions

JavaBean is a special type of Java class that follows specific conventions.

JavaBean Rules

Rule Description
Private attributes Modified with private
Provide getters/setters getXxx() and setXxx()
No-argument constructor Required
Implement Serializable Optional, for serialization

Example: Standard JavaBean

JAVA
import java.io.Serializable;

public class User implements Serializable {
    // Private attributes
    private String username;
    private String password;
    private int age;
    
    // No-argument constructor
    public User() {}
    
    // Parameterized constructor
    public User(String username, String password, int age) {
        this.username = username;
        this.password = password;
        this.age = age;
    }
    
    // Getters/Setters
    public String getUsername() {
        return username;
    }
    
    public void setUsername(String username) {
        this.username = username;
    }
    
    public String getPassword() {
        return password;
    }
    
    public void setPassword(String password) {
        if (password.length() >= 6) {
            this.password = password;
        } else {
            System.out.println("Password must be at least 6 characters");
        }
    }
    
    public int getAge() {
        return age;
    }
    
    public void setAge(int age) {
        if (age >= 0 && age <= 150) {
            this.age = age;
        } else {
            System.out.println("Invalid age");
        }
    }
    
    @Override
    public String toString() {
        return "User{username='" + username + "', age=" + age + "}";
    }
}
▶ Try it Yourself

Encapsulation in Practice

Example: Bank Account

JAVA
public class BankAccount {
    private String accountId;
    private double balance;
    private String owner;
    
    public BankAccount(String accountId, String owner) {
        this.accountId = accountId;
        this.owner = owner;
        this.balance = 0;
    }
    
    // Deposit
    public void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
            System.out.println("Deposited: " + amount + ", Balance: " + balance);
        } else {
            System.out.println("Deposit amount must be greater than 0");
        }
    }
    
    // Withdraw
    public void withdraw(double amount) {
        if (amount > 0 && amount <= balance) {
            balance -= amount;
            System.out.println("Withdrawn: " + amount + ", Balance: " + balance);
        } else if (amount > balance) {
            System.out.println("Insufficient balance");
        } else {
            System.out.println("Withdrawal amount must be greater than 0");
        }
    }
    
    // Check balance
    public double getBalance() {
        return balance;
    }
    
    public void showInfo() {
        System.out.println("Account: " + accountId + ", Owner: " + owner + ", Balance: " + balance);
    }
    
    public static void main(String[] args) {
        BankAccount account = new BankAccount("10001", "Alice");
        account.showInfo();  // Account: 10001, Owner: Alice, Balance: 0.0
        
        account.deposit(1000);  // Deposited: 1000.0, Balance: 1000.0
        account.deposit(500);   // Deposited: 500.0, Balance: 1500.0
        account.withdraw(200);  // Withdrawn: 200.0, Balance: 1300.0
        account.withdraw(2000); // Insufficient balance
    }
}
▶ Try it Yourself

Example: Product Price Validation

JAVA
public class Product {
    private String name;
    private double price;
    private int stock;
    
    public Product(String name, double price, int stock) {
        this.name = name;
        setPrice(price);
        setStock(stock);
    }
    
    public String getName() {
        return name;
    }
    
    public double getPrice() {
        return price;
    }
    
    public void setPrice(double price) {
        if (price >= 0) {
            this.price = price;
        } else {
            System.out.println("Price cannot be negative");
        }
    }
    
    public int getStock() {
        return stock;
    }
    
    public void setStock(int stock) {
        if (stock >= 0) {
            this.stock = stock;
        } else {
            System.out.println("Stock cannot be negative");
        }
    }
    
    // Calculate total price
    public double getTotalPrice(int quantity) {
        if (quantity > 0 && quantity <= stock) {
            return price * quantity;
        } else {
            System.out.println("Invalid quantity");
            return 0;
        }
    }
    
    @Override
    public String toString() {
        return name + " - $" + price + " (Stock: " + stock + ")";
    }
}
▶ Try it Yourself

Getter/Setter Naming Rules

Attribute Type Getter Setter
boolean married isMarried() setMarried()
String name getName() setName()
int age getAge() setAge()
⚠️ Special case: For boolean types, the getter uses is prefix, not get.

❓ Frequently Asked Questions

Q Why not just use public attributes?
A Public attributes provide no access control. Setters can add validation logic to protect data integrity.
Q Do all attributes need getters/setters?
A Not necessarily. Read-only attributes only need getters. Write-only attributes only need setters.
Q What's the difference between constructors and setters?
A Constructors are called when creating objects. Setters modify attributes after the object is created.

📖 Summary

📝 Exercises

  1. Student class: Define a Student class with encapsulated attributes, validate score between 0-100
  2. Date class: Define a date class with encapsulated year/month/day, provide date validation
  3. BankAccount improvement: Add password validation, require password for withdrawals

Next Lesson

In the next lesson, we'll learn about Inheritance — an important mechanism for code reuse.

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏