1. 概述

本文系统梳理 Java 中的面向对象编程(OOP)核心概念,涵盖 类、对象、抽象、封装、继承、多态 等六大基石。这些不是教科书式的概念堆砌,而是结合实战视角的提炼,帮你避开常见设计“坑”,写出更健壮、可维护的代码。

2. 类(Class)

类是创建对象的模板或蓝图,定义了对象的属性(字段)和行为(方法)。一个典型的类包含:

  • 成员字段(Member Fields)
  • 成员方法(Member Methods)
  • 构造方法(Constructor)

构造方法用于初始化对象实例。一个类可以有多个构造方法,实现重载(后续会讲)。

public class Car {
 
    // 成员字段
    private String type;
    private String model;
    private String color;
    private int speed;
 
    // 构造方法
    public Car(String type, String model, String color) {
        this.type = type;
        this.model = model;
        this.color = color;
    }
     
    // 成员方法
    public int increaseSpeed(int increment) {
        this.speed = this.speed + increment;
        return this.speed;
    }
}

✅ 建议:字段尽量私有(private),通过公共方法暴露行为,这是封装的基础。

3. 对象(Object)

对象是类的实例,通过 new 关键字调用构造方法创建。

Car veyron = new Car("Bugatti", "Veyron", "crimson");
Car corvette = new Car("Chevrolet", "Corvette", "black");

上面代码创建了两个 Car 类的实例。每个对象都有自己独立的状态(字段值),但共享类定义的行为(方法)。

⚠️ 注意:对象创建是运行时行为,类是编译时概念。

4. 抽象(Abstraction)

抽象的核心是 隐藏复杂实现,暴露简单接口。就像你不需要懂电路原理也能用电脑一样,调用方只需知道“怎么用”,而不用关心“怎么实现”。

在 Java 中,抽象主要通过两种方式实现:

  • abstract class(抽象类)
  • interface(接口)

例如,定义一个 Vehicle 抽象类或接口,只声明 start()stop() 等行为,具体怎么启动(燃油点火 or 电机驱动)由子类决定。

public abstract class Vehicle {
    public abstract void start();
    public abstract void stop();
}

这样上层代码只需依赖 Vehicle,无需关心具体车型,大大提升扩展性。

5. 封装(Encapsulation)

封装的本质是 把对象的内部状态“藏起来”,只允许通过公开的方法进行访问和修改。这是面向对象的“数据保护机制”。

典型做法:

  • 字段用 private
  • 提供 public 的 getter/setter 方法
public class Car {
    private int speed;

    public int getSpeed() {
        return speed;
    }

    public void setSpeed(int speed) {
        if (speed < 0) {
            throw new IllegalArgumentException("Speed cannot be negative");
        }
        this.speed = speed;
    }
}

✅ 封装的好处:

  • 控制访问权限
  • 加入校验逻辑(如上例的速度不能为负)
  • 内部实现变化不影响外部调用

❌ 反模式:把所有字段设为 public,等于裸奔,后期维护寸步难行。

6. 继承(Inheritance)

继承是 子类自动获得父类属性和方法的机制,形成 IS-A 关系。比如 Car IS-A Vehicle

Java 使用 extends 关键字实现继承:

public class Car extends Vehicle { 
    private int numberOfGears;

    public void openDoors() {
        // 开门逻辑
    }
}

6.1 为什么需要继承?

假设我们要设计一个车辆管理系统,汽车、卡车、公交车都有共性(轮子、启动、停止)。把这些共性提取到 Vehicle 父类:

public class Vehicle {
    private int wheels;
    private String model;

    public void start() {
        System.out.println("Vehicle starting...");
    }
    
    public void stop() {
        System.out.println("Vehicle stopping...");
    }
    
    public void honk() { 
        System.out.println("Beep!");
    }
}

子类 Car 自动拥有这些能力,还能添加自己特有的功能(如开门)。

6.2 继承层级与多级继承

Java 只支持单继承(一个类只能 extends 一个父类),但支持多级继承:

public class ArmoredCar extends Car {
    private boolean bulletProofWindows;
    
    public void remoteStartCar() {
        System.out.println("Starting via remote control...");
    }
}

此时 ArmoredCarCarVehicle,形成继承链,ArmoredCar 拥有三层类的所有非私有成员。

6.3 方法重写(Method Overriding)

子类可以重写父类的方法,实现自己的逻辑。这是多态的基础。

比如,Vehiclehonk() 是普通喇叭声,而 Car 想换成定制音效:

public class Car extends Vehicle {  

    @Override
    public void honk() { 
        System.out.println("Vroom! Custom car horn!");
    }
}

⚠️ 注意:

  • 必须加 @Override 注解,避免拼写错误导致“新建方法”而非重写
  • 重写方法的访问权限不能比父类更严格(如父类 protected,子类不能 private

7. 多态(Polymorphism)

多态是 OOP 最强大的特性之一,同一个接口,多种实现。Java 中有两种多态:

7.1 编译时多态(静态多态)—— 方法重载(Overloading)

同一个类中,方法名相同但参数列表不同(类型、个数、顺序)。

public class TextFile extends GenericFile {
    public String read() {
        return this.getContent().toString();
    }
 
    public String read(int limit) {
        return this.getContent().toString().substring(0, limit);
    }
 
    public String read(int start, int stop) {
        return this.getContent().toString().substring(start, stop);
    }
}

调用时根据传参自动匹配对应方法,编译期就确定了调用哪个,所以叫“编译时多态”。

7.2 运行时多态(动态多态)—— 方法重写(Overriding)

父类引用指向子类对象,调用被重写的方法时,实际执行的是子类的版本。

public class GenericFile {
    public String getFileInfo() {
        return "Generic File Impl";
    }
}

public class ImageFile extends GenericFile {
    @Override
    public String getFileInfo() {
        return "Image File Impl: " + width + "x" + height;
    }
}

使用示例:

GenericFile file1 = new GenericFile();
GenericFile file2 = new ImageFile(); // 父类引用指向子类对象

System.out.println(file1.getFileInfo()); // 输出: Generic File Impl
System.out.println(file2.getFileInfo()); // 输出: Image File Impl: ...

file2 虽然是 GenericFile 类型,但实际对象是 ImageFile,所以调用的是子类重写的 getFileInfo()。这就是运行时多态,方法调用在运行时才动态绑定。

8. 总结

本文从实战角度重新梳理了 Java OOP 的六大核心概念:

概念 关键词 Java 实现方式
模板 class
对象 实例 new
抽象 暴露接口 abstract class, interface
封装 隐藏状态 private + getter/setter
继承 IS-A 关系 extends
多态 一接口多实现 重载(Overload)+ 重写(Override)

这些不是孤立的概念,而是协同工作的设计体系。掌握它们,才能写出真正面向对象的代码,而不是“用 Java 写的面向过程程序”。

文中所有代码示例已托管至 GitHub:https://github.com/dev-tutorials/java-oop-concepts


原始标题:Object-Oriented-Programming Concepts in Java