Java封装 #
一、封装概述 #
封装是面向对象三大特性之一,它将数据(属性)和操作数据的方法绑定在一起,并隐藏内部实现细节。
1.1 封装的好处 #
- 隐藏实现细节
- 保护数据安全
- 提供统一访问接口
- 增强代码可维护性
二、访问修饰符 #
2.1 四种访问修饰符 #
| 修饰符 | 同一类 | 同一包 | 子类 | 其他 |
|---|---|---|---|---|
| public | ✓ | ✓ | ✓ | ✓ |
| protected | ✓ | ✓ | ✓ | ✗ |
| 默认 | ✓ | ✓ | ✗ | ✗ |
| private | ✓ | ✗ | ✗ | ✗ |
2.2 使用示例 #
java
public class Person {
// private:只能在本类访问
private String name;
// 默认:同包可访问
String address;
// protected:子类和同包可访问
protected int age;
// public:任何地方可访问
public String phone;
}
2.3 修饰符使用规则 #
java
// 类:public 或 默认
public class PublicClass { }
class DefaultClass { }
// 成员变量:通常使用private
private String name;
// 方法:根据需要选择
public void publicMethod() { }
private void privateMethod() { }
protected void protectedMethod() { }
void defaultMethod() { }
三、getter和setter #
3.1 基本用法 #
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) {
this.age = age;
}
}
3.2 命名规范 #
java
public class Demo {
private String name; // getName / setName
private boolean active; // isActive / setActive
private int count; // getCount / setCount
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isActive() {
return active;
}
public void setActive(boolean active) {
this.active = active;
}
}
3.3 在setter中添加验证 #
java
public class Person {
private String name;
private int age;
public void setAge(int age) {
if (age < 0 || age > 150) {
throw new IllegalArgumentException("年龄不合法");
}
this.age = age;
}
public void setName(String name) {
if (name == null || name.trim().isEmpty()) {
throw new IllegalArgumentException("姓名不能为空");
}
this.name = name.trim();
}
}
3.4 只读属性 #
java
public class Person {
private String id; // 只读属性
public Person(String id) {
this.id = id;
}
// 只有getter,没有setter
public String getId() {
return id;
}
}
四、封装示例 #
4.1 银行账户 #
java
public class BankAccount {
private String accountNumber;
private String owner;
private double balance;
public BankAccount(String accountNumber, String owner) {
this.accountNumber = accountNumber;
this.owner = owner;
this.balance = 0;
}
// 存款
public void deposit(double amount) {
if (amount <= 0) {
throw new IllegalArgumentException("存款金额必须大于0");
}
balance += amount;
}
// 取款
public void withdraw(double amount) {
if (amount <= 0) {
throw new IllegalArgumentException("取款金额必须大于0");
}
if (amount > balance) {
throw new IllegalArgumentException("余额不足");
}
balance -= amount;
}
// 查询余额
public double getBalance() {
return balance;
}
public String getAccountNumber() {
return accountNumber;
}
public String getOwner() {
return owner;
}
}
4.2 学生类 #
java
public class Student {
private String id;
private String name;
private int[] scores;
public Student(String id, String name) {
this.id = id;
this.name = name;
this.scores = new int[0];
}
public void setScores(int[] scores) {
for (int score : scores) {
if (score < 0 || score > 100) {
throw new IllegalArgumentException("分数必须在0-100之间");
}
}
this.scores = scores.clone(); // 防止外部修改
}
public double getAverageScore() {
if (scores.length == 0) return 0;
int sum = 0;
for (int score : scores) {
sum += score;
}
return (double) sum / scores.length;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
五、封装原则 #
5.1 最小化访问权限 #
java
public class Demo {
// 成员变量:private
private String name;
// 内部方法:private
private void validate() {
}
// 公共接口:public
public void doSomething() {
validate();
}
}
5.2 保护可变对象 #
java
public class Team {
private List<String> members = new ArrayList<>();
// 错误:直接返回引用
// public List<String> getMembers() {
// return members;
// }
// 正确:返回副本
public List<String> getMembers() {
return new ArrayList<>(members);
}
// 正确:返回不可修改视图
public List<String> getMembersUnmodifiable() {
return Collections.unmodifiableList(members);
}
// 通过方法修改
public void addMember(String name) {
members.add(name);
}
public void removeMember(String name) {
members.remove(name);
}
}
5.3 不可变对象 #
java
public final class ImmutablePerson {
private final String name;
private final int age;
public ImmutablePerson(String name, int age) {
this.name = name;
this.age = age;
}
// 只有getter,没有setter
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
六、Lombok简化 #
6.1 使用Lombok #
java
import lombok.Getter;
import lombok.Setter;
public class Person {
@Getter @Setter
private String name;
@Getter @Setter
private int age;
}
6.2 @Data注解 #
java
import lombok.Data;
@Data // 自动生成getter、setter、toString、equals、hashCode
public class Person {
private String name;
private int age;
}
七、总结 #
| 概念 | 说明 |
|---|---|
| private | 只能在本类访问 |
| 默认 | 同包可访问 |
| protected | 子类和同包可访问 |
| public | 任何地方可访问 |
| getter | 获取属性值 |
| setter | 设置属性值 |
封装要点:
- 成员变量使用private
- 提供public的getter/setter方法
- 在setter中添加验证逻辑
- 保护可变对象不被直接修改
- 遵循最小权限原则
最后更新:2026-03-26