1. 引言
面向对象编程(OOP)试图以我们大脑认知世界的方式来建模现实世界。
本文将从我们如何观察和简化现实出发,深入探讨 OOP 的核心思想,并通过现实中的例子帮助你理解其本质。
2. 我们如何看待世界
大脑并不是直接处理世界的全貌,而是通过简化来理解复杂信息。否则,它根本无法处理每秒接收到的海量信息。
我们对世界进行建模,抓住关键特征,忽略次要细节:
3. 使用类进行建模
这种建模过程依赖于识别事物之间的相似性。当大脑发现两个事物足够相似时,就会把它们归为一类。
比如,我们看到“狗”,就会想到它有体重、颜色等属性,以及吠叫、摇尾巴等行为:
狗、猫、桌子都有四条腿,但我们不会把桌子归为“狗”的类别。不过狗和猫足够相似,我们可以把它们归入“哺乳动物”或“动物”这个更大的类:
我们也可以定义更广义的类别,比如“四条腿的东西”:
✅ 这种分类在编程中被称为“类(class)”。
4. 对象:现实世界中的类实例
类代表的是我们对现实事物的抽象,它们本身并不存在于现实中。
现实中存在的是具体的“对象”,比如“Lassie”或“Laika”:
当我们说“我今天看到一只狗”,其实是在说“我今天看到一个东西,我把它归类为狗”。
✅ 类是抽象,对象是具体实例。
5. 封装:数据与行为的结合
狗有体重、颜色等属性,也有吠叫、坐下等行为。
这些数据(字段)和行为(方法)应该封装在类中:
public class Dog {
private String name;
private String color;
public void bark() {
System.out.println("Woof!");
}
}
✅ 封装的本质是将数据和操作数据的行为封装在同一个类中。
现实世界中,我们不会把狗放进一个机器里让它坐下,而是直接对狗说“坐下”,狗自己会改变状态。
6. 关系的力量
对象不仅能独立存在,还能与其他对象协作。
比如,当主人扔出一个球,狗会跑过去捡回来。这个行为依赖于主人、狗和球三者之间的关系:
✅ 对象之间的协作能产生远超单个对象能力的复杂行为。
这些关系在编程中可以是继承、组合、聚合等形式。我们有专门的文章讲解它们的区别。
7. 可见性:隐藏不应该被看到的细节
有些数据和行为我们不希望外部看到,比如狗的内脏结构。
这些是实现细节,应该被隐藏起来。
✅ 类应该暴露简洁的行为接口,隐藏复杂的实现细节。
在 Java 中,我们通过访问修饰符(private、protected、public)来控制可见性。
public class Dog {
private String name; // 只有类内部可以访问
public void setName(String name) { // 提供公开方法修改
this.name = name;
}
}
8. 状态处理:可变与不可变对象
对象可以是可变的(mutable)或不可变的(immutable):
- ✅ 可变对象:状态可以改变,如狗的体重
- ✅ 不可变对象:状态不可变,如钞票的面值
Java 中默认对象是可变的。要创建不可变对象,需要额外设计:
public final class ImmutableDog {
private final String name;
public ImmutableDog(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
9. 引用:如何指向特定对象
我们通过“引用”来标识特定对象。例如,一个家庭有多个狗,我们通过名字来区分:
✅ 变量是对象的引用,变量的值可以变化,指向不同的对象。
Dog myDog = new Dog("Buddy");
myDog = new Dog("Max"); // 指向另一个对象
10. 不变的事物
有些事物是恒定不变的,比如“地球”始终指同一个星球。
在编程中,我们使用常量来表示这种不变性:
public class Constants {
public static final String PLANET = "Earth";
}
⚠️ 常量一旦赋值就不能再更改。
11. 常量 vs 不可变对象
- ✅ 常量:变量不能指向另一个对象(final)
- ✅ 不可变对象:对象内部状态不能改变
它们是两个独立的概念,可以组合使用:
是否 final | 是否不可变 | 说明 |
---|---|---|
否 | 否 | 最灵活,也最容易出错 |
是 | 否 | 引用不变,内部状态可变 |
否 | 是 | 引用可变,对象状态不变 |
是 | 是 | 完全不可变,最安全 |
12. 总结
面向对象编程之所以强大,是因为它模仿了人类大脑认知世界的方式。
通过类、对象、封装、关系、可见性、状态管理等机制,OOP 提供了一种自然、直观的方式来建模现实世界。
掌握这些核心概念,不仅能帮助你写出更清晰、可维护的代码,也能提升你对软件设计本质的理解。