1. 引言

面向对象编程(OOP)试图以我们大脑认知世界的方式来建模现实世界。

本文将从我们如何观察和简化现实出发,深入探讨 OOP 的核心思想,并通过现实中的例子帮助你理解其本质。


2. 我们如何看待世界

大脑并不是直接处理世界的全貌,而是通过简化来理解复杂信息。否则,它根本无法处理每秒接收到的海量信息。

我们对世界进行建模,抓住关键特征,忽略次要细节:

modeling mind


3. 使用类进行建模

这种建模过程依赖于识别事物之间的相似性。当大脑发现两个事物足够相似时,就会把它们归为一类。

比如,我们看到“狗”,就会想到它有体重、颜色等属性,以及吠叫、摇尾巴等行为:

classification 1

狗、猫、桌子都有四条腿,但我们不会把桌子归为“狗”的类别。不过狗和猫足够相似,我们可以把它们归入“哺乳动物”或“动物”这个更大的类:

classification 2

我们也可以定义更广义的类别,比如“四条腿的东西”:

classification 3

这种分类在编程中被称为“类(class)”


4. 对象:现实世界中的类实例

类代表的是我们对现实事物的抽象,它们本身并不存在于现实中。

现实中存在的是具体的“对象”,比如“Lassie”或“Laika”:

objects 1

当我们说“我今天看到一只狗”,其实是在说“我今天看到一个东西,我把它归类为狗”。

类是抽象,对象是具体实例


5. 封装:数据与行为的结合

狗有体重、颜色等属性,也有吠叫、坐下等行为。

这些数据(字段)和行为(方法)应该封装在类中:

public class Dog {
    private String name;
    private String color;

    public void bark() {
        System.out.println("Woof!");
    }
}

封装的本质是将数据和操作数据的行为封装在同一个类中

现实世界中,我们不会把狗放进一个机器里让它坐下,而是直接对狗说“坐下”,狗自己会改变状态。

encapsulation 2


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 提供了一种自然、直观的方式来建模现实世界。

掌握这些核心概念,不仅能帮助你写出更清晰、可维护的代码,也能提升你对软件设计本质的理解。


原始标题:Object-Orientation in the Real World