面向对象的封装本质
封装是面向对象三大特性(封装、继承、多态)的基石,它通过隐藏实现细节和暴露有限接口,降低系统耦合度。想象灯泡的开关设计:
// 低耦合设计:只暴露必要接口
Light light = new Light();
light.turnOn(); // 用户无需了解内部电路
// 高耦合设计:暴露实现细节
Light light2 = new Light();
light2.打开电路1(); // 用户需了解内部实现
light2.打开电路2();
light2.打开电路3();
封装的必要性
当业务需求变化时,未封装的代码将面临灾难性修改。以用户年龄校验为例:
// 未封装:100处赋值点需要修改
public class Person {
public int age; // 直接暴露属性
}
// 封装后:只需修改setAge方法
public class Person {
private int age;
public void setAge(int age) {
this.age = Math.max(0, Math.min(age, 100));
}
}
访问控制四重门
Java提供精确的访问控制机制:
| 修饰符 | 同类 | 同包 | 子类 | 其他包 |
|---|---|---|---|---|
private | ✔️ | |||
| (默认) | ✔️ | ✔️ | ||
protected | ✔️ | ✔️ | ✔️ | |
public | ✔️ | ✔️ | ✔️ | ✔️ |
protected的跨包访问:
// 子类可访问父类protected成员
public class PersonSubClass extends Person {
public PersonSubClass() {
this.id = 1; // 允许访问protected字段
}
}
JavaBean规范与序列化
遵循JavaBean规范是实现框架集成的关键:
public class Cat {
private String name;
private boolean cute;
// 非布尔属性getter
public String getName() { return name; }
// 布尔属性getter
public boolean isCute() { return cute; }
// 序列化演示
public static void main(String[] args) {
Cat cat = new Cat("喵", true);
String json = JSON.toJSONString(cat); // 依赖getter
Cat parsedCat = JSON.parseObject(json, Cat.class); // 依赖setter
}
}
核心规范:
- 非布尔属性:
getXxx() - 布尔属性:
isXxx() - 设置方法:
setXxx()
静态工厂方法实践
Effective Java推荐的创建模式,相比构造器优势明显:
public class Cat {
private static final Cat INVALID_CAT = new Cat("Invalid", true);
private Cat(String name, boolean cute) { // 构造器私有化
// ...
}
// 1. 方法名自描述
public static Cat newCuteCat(String name) {
if (name == null) return INVALID_CAT;
// 3. 返回子类对象
if (name.contains("white")) return new WhiteCat(name);
// 4. 复用已有对象
return name.equals("default") ? DEFAULT_CAT : new Cat(name, true);
}
// 2. 不强制创建新对象
public static Cat getInstance() {
return CACHE.get();
}
}
五大优势:
- 方法名明确创建意图(
newCuteCatvsnew Cat(true)) - 避免不必要的对象创建
- 可返回任意子类型
- 实现对象缓存复用
- 服务提供者框架的基础
Builder模式解决参数膨胀
当构造参数过多时,Builder模式提供优雅解决方案:
Person person = Person.builder()
.withFirstName("张")
.withLastName("三")
.withAge(30)
.withAddress("北京市")
.withPhone("13800138000")
.build();
实现要点:
- 创建静态内部Builder类
- 链式设置方法(返回Builder自身)
build()方法返回最终对象
突破包级访问限制
在特殊场景下,可通过同名包突破访问限制:
// 在com.github.hcsp包中创建类
package com.github.hcsp;
public class PackageAccessor {
void access() {
InternalClass obj = new InternalClass(); // 访问包级私有类
}
}
Java模块化系统
JDK9引入的模块系统提供更强封装:
module com.example.myapp {
exports com.example.api; // 导出公共API包
hides com.example.internal; // 隐藏实现包
}