首页 / Java 入门教程 / 面向对象思想概述

Java 入门教程

面向对象思想概述

本教程共 100 篇 · 第 29 篇 · 更新于 2026-08-05 · 约 6 分钟阅读

JavaJava 入门教程面向对象封装继承多态

29. 面向对象思想概述

本节目标:理解面向对象为什么出现、它和面向过程的差别,并记住封装、继承、多态这三大特性的核心含义。

前面写的代码都是”按步骤一步步走”,这种思路叫面向过程。程序小还好,一大就乱。面向对象(OOP)换了个角度看世界:把数据和操作数据的行为打包成一个个”对象”。这一章不写具体语法,先把地图看明白,后面几章再逐个落地。

从”过程”到”对象”

面向过程像写菜谱:第一步切菜、第二步下锅、第三步装盘,强调动作顺序。面向对象像开餐厅:有”厨师”对象、“菜品”对象、“订单”对象,每个对象管自己的一摊事,互相配合完成目标。

// 面向过程:关心怎么做
void cook(String name) { ... }

// 面向对象:关心谁来做
Chef chef = new Chef();
chef.cook("红烧肉");
```bash

后者把"会做菜"的能力和数据(厨师姓名、等级)绑在 Chef 对象上,用起来更自然。当系统变复杂,"谁来做""怎么做"更不容易乱。

> [!NOTE]
> 面向过程不等于落后。小程序、脚本、算法题里用面向过程更顺手。真正的大型工程才需要面向对象的组织能力。

## 封装:把细节藏起来

封装是把对象的内部数据和保护它的方法捆在一起,只留必要的接口给外面用。就像开车,你踩油门就能走,不用懂发动机怎么点火。

好处:外面只能按你规定的方式用,内部怎么实现随你改,不影响别人。后面学 private 和 getter/setter 就是封装的具体手段。封装降低耦合,是大型项目能协作的前提。

### 封装解决什么问题

假设你写了个类,里面有温度字段。如果直接暴露,外面可以随便设成绝对零度以下,物理上就不合法了。封装让你在 setter 里加校验:

```java
public class Temperature {
    private double celsius;   // 私有,外面不能直接改

    public void setCelsius(double c) {
        if (c < -273.15) {
            throw new IllegalArgumentException("低于绝对零度");
        }
        this.celsius = c;
    }
}

外面调 setCelsius(-300) 直接被拒绝,规则被保护住。这就是封装的价值:在”入口”挡掉非法数据。

继承:复用已有的能力

继承让一个新类直接拥有旧类的属性和方法,不用重写一遍。比如”学生”和”老师”都是”人”,都有姓名年龄,那就先写个 Person,再让 Student、Teacher 继承它。

class Person { String name; }
class Student extends Person { int grade; }   // Student 自动有了 name
```bash

继承表达的是"是一个"的关系:Student 是一个 Person。它把共性往上提,差异往下放,避免重复代码。

> [!NOTE]
> Java 只支持**单继承**:一个类只能有一个父类。想复用多份能力,用后面讲的接口(interface)。单继承让类之间的关系更清晰,不会陷入"多重继承"的歧义泥潭。

### 继承的两个陷阱

一是"为了继承而继承"。如果两个类只是碰巧有相同字段,没有"是一个"的关系,硬继承只会让类层次越来越别扭。比如 Car 和 Engine,不应该是继承关系,应该是组合关系(Car 有一个 Engine)。

二是"层次过深"。A 继承 B,B 继承 C,C 继承 D……五六层之后,改一处底层代码心里都没底。一般建议继承层次不超过三层。

## 多态:同一动作,不同表现

多态指"同一方法,不同对象表现出不同行为"。比如 Animal 有个 shout 方法,Cat 叫出"喵",Dog 叫出"汪"。调用时只管 `animal.shout()`,具体叫什么由运行时真正对象的类型决定。

这让代码能"面向父类写,灵活接子类",是面向对象最灵活也最难懂的一块。后面会专门用一章展开。多态让程序"对扩展开放、对修改关闭",是框架设计的基石。

### 多态为什么强大

假设有个系统要处理各种形状(圆、方、三角)的面积。如果没有多态,得写一堆 if-else 判断类型。有了多态,只需:

```java
Shape s = getSomeShape();   // 可能是圆,可能是方
s.area();                   // 自动调正确版本

新增一种形状,加一个子类就行,旧代码零改动。这就是”对扩展开放、对修改关闭”。

三大特性串起来看

封装解决”怎么藏”,继承解决”怎么复用”,多态解决”怎么灵活”。三者配合,才能写出既稳又能长个子的代码。初学时不用强求一次全懂,先建立印象即可。

特性核心问题手段关键词
封装怎么保护数据private、getter/setter隐藏细节
继承怎么复用代码extends是一个
多态怎么灵活替换父类引用指向子类对象同一接口不同实现

为什么学面向对象

  • 代码更好组织:相关的数据和行为待在一起,找起来快。
  • 更易复用:继承、组合避免重复造轮子。
  • 更易维护:改一处实现,接口不变就不影响其他代码。
  • 更抗变化:多态让新增类型不改动旧逻辑。
Tip

初学不必强求”一开始就面向对象设计”。先把类和对象的基本写法练熟,三大特性会在后面逐章落地。这章先把地图看明白,别急着背定义。

面向对象不是银弹

也要说句公道话:不是所有问题都该面向对象。简单脚本、纯计算,面向过程反而更直接。Java 强制你用类组织代码,但并不意味着每行都要追求”完美对象”。理解思想,比套用术语重要。

速查表

概念一句话
类(Class)对象的”图纸”
对象(Object)类的”实例”
封装数据私有化,方法公开化
继承is-a,子类复用父类
多态同一调用,不同行为
抽象只定义接口,不写实现
组合has-a,优先于继承

常见疑问

Q:面向对象和面向过程到底哪个更好? 没有更好,只有更适合。算法题、脚本工具适合面向过程;中大型软件、团队协作适合面向对象。Java 是面向对象语言,所以这本教程后面的代码都以 OOP 为主。

Q:封装就是 private + getter/setter 吗? 这是最常见的封装手段,但不等于全部。只读字段可以不写 setter;复杂校验逻辑放 setter 里;方法也可以封装——private 方法对外不可见,但内部调用。

Q:为什么现在推荐”组合优于继承”? 继承层次一深,改父类影响所有子类,容易失控。组合是把对象当作字段注入,灵活且低耦合。后面学到接口和依赖注入时,会深讲这一点。