Java: Encapsulation

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

1. What is Encapsulation

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

(1) 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

2. 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

TEXT 📖 Display only
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
}
💡 Recommendation: Use private for attributes and access them through getter/setter methods.


3. Getters and Setters

(1) 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

TEXT 📖 Display only
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
    }
}

4. JavaBean Conventions

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

(1) 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 📖 Display only
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 + "}";
    }
}
42 logic lines (exceeds 40-line limit, display only)

5. Encapsulation in Practice

▶ Example: Bank Account

JAVA 📖 Display only
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
    }
}
42 logic lines (exceeds 40-line limit, display only)

▶ Example: Product Price Validation

JAVA 📖 Display only
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 + ")";
    }
}
45 logic lines (exceeds 40-line limit, display only)

6. 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.


7. ❓ 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.

❓ FAQ

Q Why use private fields?
A To protect data from external modification. Only controlled access through public methods.
Q Should all fields be private?
A Generally yes. Use protected if subclasses need direct access.
Q What is a JavaBean?
A A class with private fields, public getters/setters, a no-arg constructor, and implements Serializable.

📖 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

8. Next Lesson

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

Web-Tutorial.com

Web-Tutorial Tech Team

A team of developers maintaining programming tutorials. Each tutorial is written and reviewed by developers with expertise in that field. We work to keep our content accurate and reliable — if you spot an issue, please let us know.

100%

🙏 帮我们做得更好

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

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