第一部分:面向对象程序设计 - 思想与哲学
面向对象程序设计,简称OOP,是一种“自下而上”的编程思想,它将现实世界中的事物抽象成“对象”,然后通过对象之间的交互来构建复杂的软件系统,这与传统的面向过程编程(自上而下,关注“过程”和“函数”)形成了鲜明对比。

OOP的核心思想是“万物皆对象”。
OOP的四大基本特性
这是理解OOP的基石,Java语言完美地支持了这四大特性。
封装
-
是什么? 封装就是把数据(属性)和操作数据的方法(行为)捆绑在一起,形成一个独立的单元(即类),并对外部隐藏对象的内部细节,只暴露有限的接口与外界交互。
-
为什么?
(图片来源网络,侵删)- 数据安全:防止外部代码随意修改对象的内部状态,避免数据被意外破坏。
- 降低耦合:使用者只需要知道如何通过公共接口来使用对象,而不需要关心其内部的复杂实现,这就像使用电视,你只需要知道按哪个按钮换台、调音量,而不需要了解电视机内部的电路板是如何工作的。
-
如何实现? 在Java中,通过访问修饰符来实现封装:
private:私有,只能在当前类内部访问,用于隐藏类的内部数据(成员变量)。public:公有,可以被任何其他类访问,用于暴露公共的接口(方法)。protected:受保护,可以被同一包内的类或其子类访问。default(无修饰符):默认,可以被同一包内的类访问。
示例:
public class BankAccount { // 私有属性,外部无法直接访问 private double balance; // 公共方法,作为与外界交互的接口 public void deposit(double amount) { if (amount > 0) { this.balance += amount; } } public double getBalance() { // 可以在这里添加逻辑,比如检查权限 return this.balance; } }
继承
-
是什么? 继承允许一个类(称为子类或派生类)获取另一个类(称为父类或基类)的属性和方法,这形成了一个类之间的层次关系。
-
为什么?
(图片来源网络,侵删)- 代码复用:子类可以复用父类的代码,避免了重复编写相同的逻辑。
- 建立类层次结构:可以清晰地表达“是一个”(is-a)的关系。“狗”是一个“动物”,“轿车”是一个“汽车”。
-
如何实现? 在Java中,使用
extends关键字来实现继承,Java只支持单继承(一个类只能有一个直接父类),但可以通过接口实现多继承的效果。示例:
// 父类 class Animal { void eat() { System.out.println("This animal eats food."); } } // 子类 继承 父类 class Dog extends Animal { void bark() { System.out.println("The dog barks."); } } // 使用 Dog myDog = new Dog(); myDog.eat(); // 继承自 Animal 类的方法 myDog.bark(); // Dog 类自己的方法
多态
-
是什么? 多态的字面意思是“多种形态”,在OOP中,它指的是同一个接口,使用不同的实例而执行不同操作,就是允许将子类对象当作其父类对象来使用。
-
为什么?
- 灵活性和可扩展性:可以编写更通用、更灵活的代码,一个方法可以接受
Animal类型的参数,那么你就可以传入Dog、Cat等任何Animal的子类对象,而无需修改方法本身。
- 灵活性和可扩展性:可以编写更通用、更灵活的代码,一个方法可以接受
-
如何实现? 多态的实现需要三个条件:
- 继承:必须有类之间的继承关系。
- 重写:子类必须重写父类的方法。
- 向上转型:父类引用指向子类对象。
示例:
class Cat extends Animal { // 重写父类的 eat 方法 @Override void eat() { System.out.println("The cat eats fish."); } } // 一个接受 Animal 类型参数的方法 public void feedAnimal(Animal animal) { animal.eat(); // 根据传入的实际对象,调用不同的 eat() 方法 } // 使用 Animal myDog = new Dog(); // 向上转型 Animal myCat = new Cat(); // 向上转型 feedAnimal(myDog); // 输出: This animal eats food. feedAnimal(myCat); // 输出: The cat eats fish.注意:
feedAnimal方法内部调用的eat()方法,在运行时才会确定具体调用哪个,这被称为动态绑定或运行时多态。
抽象
-
是什么? 抽象是指隐藏复杂的实现细节,只向用户展示必要的特征,它关注的是“做什么”,而不是“怎么做”。
-
为什么?
- 简化问题:让我们能够专注于高层次的逻辑,而不必被底层繁琐的实现所困扰。
-
如何实现? 在Java中,抽象主要通过两种方式实现:
- 抽象方法:使用
abstract关键字声明,没有方法体,它只定义了方法的签名(名称、参数),没有具体实现。 - 抽象类:使用
abstract关键字声明,可以包含抽象方法,也可以包含具体方法,抽象类不能被实例化(不能创建对象),只能被继承。
示例:
// 抽象类 abstract class Shape { // 抽象方法,没有实现 abstract double calculateArea(); } // 具体子类 class Circle extends Shape { private double radius; public Circle(double radius) { this.radius = radius; } // 必须实现父类的抽象方法 @Override double calculateArea() { return Math.PI * radius * radius; } } - 抽象方法:使用
第二部分:Java语言 - OOP的实践者
Java语言从设计之初就是一门纯粹的面向对象语言,它的语法和特性都是为了更好地支持OOP思想。
Java中的核心OOP概念
类 与 对象
-
类:是对象的蓝图或模板,它定义了一类对象共有的属性(成员变量)和行为(方法)。
Person类可以定义name、age属性和speak()方法。 -
对象:是类的实例,是真实存在的个体。
zhangsan是Person类的一个具体对象,他的name是 "张三",age是 18。示例:
// 类的定义 class Person { String name; int age; void speak() { System.out.println("My name is " + this.name); } } // 创建对象(类的实例化) public class Main { public static void main(String[] args) { Person p1 = new Person(); // 创建一个 Person 对象 p1.name = "Alice"; p1.age = 25; p1.speak(); // 输出: My name is Alice } }
this 关键字
this 关键字在Java中代表当前对象的引用,它主要用于:
-
区分成员变量和局部变量(当它们同名时)。
-
在构造方法中调用其他构造方法(
this(...))。 -
将当前对象作为参数传递给其他方法。
示例:
class Person { String name; // 构造方法 Person(String name) { this.name = name; // this.name 指的是成员变量,name 指的是传入的参数 } }
构造方法
-
是什么? 构造方法是一种特殊的方法,用于在创建对象时进行初始化,它的名称必须与类名完全相同,且没有返回类型。
-
特点:
- 每个类至少有一个构造方法(如果没有显式定义,Java会提供一个默认的无参构造方法)。
- 在创建对象时由
new关键字自动调用。 - 可以重载(定义多个参数列表不同的构造方法)。
示例:
class Car { String brand; // 无参构造方法 Car() { this.brand = "Unknown"; } // 有参构造方法 Car(String brand) { this.brand = brand; // 使用 this 调用成员变量 } }
包
包是Java中用于组织和管理类的命名空间,它解决了类名冲突的问题,并提供了访问控制。java.util 包包含了许多工具类,如 ArrayList 和 Date。
权限修饰符 (Access Modifiers)
如前所述,public, private, protected, default 是实现封装的核心工具。
static 关键字
static 关键字可以修饰成员变量和成员方法,使其成为类级别的,而不是对象级别的。
- 静态变量:被所有该类的对象共享,存储在方法区,只有一份拷贝。
Math.PI。 - 静态方法:属于类,而不是对象,可以通过类名直接调用,无需创建对象。
Math.max(),静态方法内部不能直接访问非静态的成员变量或方法。
OOP与Java的关系
| OOP概念 | 在Java中的体现 | 关键字/机制 |
|---|---|---|
| 对象 | 类的实例 | new 关键字 |
| 类 | 对象的蓝图 | class 关键字 |
| 封装 | 数据隐藏与接口暴露 | private, public, getters/setters |
| 继承 | 代码复用与层次关系 | extends 关键字 |
| 多态 | 同一接口,不同实现 | 方法重写、向上转型、@Override 注解 |
| 抽象 | 隐藏实现细节,定义契约 | abstract 关键字、接口 |
| 构造 | 对象初始化 | 构造方法 |
| 引用 | 当前对象 | this 关键字 |
| 组织 | 命名空间管理 | package 语句 |
学习建议:
- 先理解思想,再学习语法:不要一开始就陷入Java的语法细节,先深刻理解OOP的四大特性,思考它们解决了什么问题。
- 多画图,多思考:用UML图来表示类、对象、继承和关联关系,这能极大地帮助你理清复杂的系统结构。
- 动手实践:尝试用OOP的思想去设计一些小系统,比如一个简单的图书管理系统、一个动物园管理系统等,在实践中你会遇到各种问题,从而加深对OOP的理解。
- 阅读优秀代码:阅读Java标准库(如
java.util包)的源码,看看大师们是如何运用OOP思想来设计这些通用、健壮的类的。
掌握了面向对象思想和Java语言,你就拥有了构建大型、复杂、可维护、可扩展软件的强大武器。
