Skip to content
第 16 / 250 章后端⏱ 10 分钟阅读

第 16 章:封装

学习目标

  • 理解封装的本质和价值
  • 掌握四种访问修饰符
  • 学会 JavaBean 规范

一、什么是封装?

封装 = 把数据藏起来,对外暴露受控的访问方式。

反例:没有封装

java
public class User {
    public String name;        // ❌ 外部可直接修改
    public int age;
}

User u = new User();
u.name = "";                  // ❌ 可以设置为空字符串
u.age = -100;                 // ❌ 可以设置为负数

正例:封装后

java
public class User {
    private String name;       // ① 私有字段
    private int age;

    public String getName() { return name; }
    public void setName(String name) {
        if (name == null || name.isEmpty()) {
            throw new IllegalArgumentException("姓名不能为空");
        }
        this.name = name;
    }

    public int getAge() { return age; }
    public void setAge(int age) {
        if (age < 0 || age > 150) {
            throw new IllegalArgumentException("年龄不合法");
        }
        this.age = age;
    }
}

二、四种访问修饰符

修饰符同类同包子类其他包
private
默认(无)
protected
public

三、JavaBean 规范

JavaBean 是符合特定约定的类:

  1. 类必须是 public
  2. 字段必须是 private
  3. 必须有无参构造器
  4. getter / setter 暴露字段
java
public class User implements java.io.Serializable {
    private static final long serialVersionUID = 1L;

    private Long id;
    private String name;

    public User() { }                            // ① 无参构造器

    public Long getId() { return id; }           // ② getter
    public void setId(Long id) { this.id = id; } // ③ setter

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
}

IDEA 右键 → Generate → Getters and Setters 一键生成。

四、封装的实际价值

4.1 数据校验

java
public void setAge(int age) {
    if (age < 0 || age > 150) {
        throw new IllegalArgumentException("年龄不合法");
    }
    this.age = age;
}

4.2 计算属性

java
public class Circle {
    private double radius;

    public double getArea() {                  // ① 计算属性,无需字段
        return Math.PI * radius * radius;
    }
}

4.3 延迟初始化

java
public class Config {
    private Properties props;

    public Properties getProps() {             // ② 用到时才加载
        if (props == null) {
            props = loadProps();
        }
        return props;
    }
}

4.4 不变性

java
public final class ImmutableUser {              // ① final 类不可继承
    private final String name;                  // ② final 字段不可修改
    private final int age;

    public ImmutableUser(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // 只有 getter,没有 setter
    public String getName() { return name; }
    public int getAge() { return age; }
}

StringInteger 等都是不可变对象(详见第 23 章)。

五、本章小结

要点关键
封装本质把数据藏起来,对外暴露受控方法
访问修饰符private / 默认 / protected / public
JavaBean 规范private 字段 + getter/setter + 无参构造
封装的价值校验、计算属性、延迟初始化、不变性

动手练习

练习 1:基础题

设计一个 BankAccount 类(银行账户),封装:

java
private String accountNumber  // 账号(不可修改)
private String owner          // 户主(不可修改)
private BigDecimal balance    // 余额(只能通过 deposit/withdraw 修改)

public void deposit(BigDecimal amount)    // 存款(必须 > 0)
public void withdraw(BigDecimal amount)   // 取款(必须 <= balance)

下一章第 17 章:继承

本站基于 VitePress 构建 · 由 Codebook 团队维护