Java 初识面向对象 + 类与对象 + 封装核心
这是 Java 编程的最重要基础,几乎所有后续内容(继承、多态、接口、设计模式、框架)都建立在这三块基石之上。
下面用最清晰、最结构化的方式帮你把这部分真正搞懂。
一、什么是面向对象编程(OOP)?
面向对象编程的核心思想是:把现实世界中的事物抽象成“对象”,然后通过对象之间的协作来完成任务。
对比面向过程(POP):
| 维度 | 面向过程(C语言风格) | 面向对象(Java风格) |
|---|---|---|
| 核心单位 | 函数 + 数据(分开) | 对象(数据 + 行为一起) |
| 思考方式 | 先做什么,再做什么 | 有哪些对象,它们能做什么 |
| 代码组织 | 函数调用链 | 对象之间的消息传递(方法调用) |
| 复用方式 | 函数复用 | 对象复用、类复用、继承、组合 |
| 典型代表 | C、Fortran、早期的 BASIC | Java、C#、Python、C++、Kotlin |
Java 强制面向对象:所有代码必须写在类中,没有全局函数(除了 static 方法)。
二、类(Class)与对象(Object)的本质区别
| 概念 | 含义 | 类比(现实世界) | 代码中的对应物 | 内存中状态 |
|---|---|---|---|---|
| 类 | 对象的模板 / 蓝图 / 抽象描述 | 汽车的设计图纸 | class 关键字定义的结构 | 只加载一份 |
| 对象 | 根据类创建的具体实例 | 一辆具体的宝马X5 | new 出来的东西 | 每个对象一份内存 |
一句话总结:
类是抽象的,对象是具体的。
类定义了所有对象共有的属性和行为,对象拥有自己的数据。
三、类与对象的代码写法(最基础写法)
// 1. 定义类(模板)
public class Student {
// 属性(成员变量 / 字段 / Field)
String name; // 姓名
int age; // 年龄
char gender; // 性别
double score; // 成绩
// 行为(方法 / 函数)
public void study() {
System.out.println(name + " 正在学习...");
}
public void showInfo() {
System.out.println("姓名:" + name);
System.out.println("年龄:" + age);
System.out.println("性别:" + gender);
System.out.println("成绩:" + score);
}
}
// 2. 创建对象、使用对象
public class TestStudent {
public static void main(String[] args) {
// 创建对象(实例化)
Student s1 = new Student(); // s1 是一个引用变量,指向堆中的对象
// 给对象赋值(给属性赋值)
s1.name = "张三";
s1.age = 18;
s1.gender = '男';
s1.score = 88.5;
// 调用对象的行为(方法)
s1.study();
s1.showInfo();
System.out.println("----------------");
// 再创建一个不同的对象
Student s2 = new Student();
s2.name = "李四";
s2.age = 20;
s2.gender = '女';
s2.score = 95.0;
s2.study();
s2.showInfo();
}
}
运行结果(关键点):
- s1 和 s2 是两个独立的对象,它们有自己的一份 name、age 等数据。
- 类只定义一次,对象可以创建无数个。
四、封装(Encapsulation)—— Java OOP 的第一基石
封装的核心目的:
隐藏内部实现细节,对外只暴露必要的操作接口,保护数据安全,提高代码可维护性。
封装的三个层次(由弱到强):
- 最弱封装:所有属性都是 public(不推荐)
public String name;
public int age;
- 中等封装(最常见写法):
private String name; // 私有化属性
private int age;
// 提供公共的 getter 和 setter 方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name; // this 指当前对象
}
public int getAge() {
return age;
}
public void setAge(int age) {
if (age >= 0 && age <= 150) { // 加入校验
this.age = age;
} else {
System.out.println("年龄不合法!");
}
}
- 强封装(推荐现代写法):
- 属性全部 private final(尽可能不可变)
- 只提供 getter,不提供 setter(或 setter 非常严格)
- 通过构造函数一次性初始化
public class Student {
private final String name;
private final int age;
private final char gender;
// 构造函数(初始化)
public Student(String name, int age, char gender) {
this.name = name;
if (age >= 0 && age <= 150) {
this.age = age;
} else {
this.age = 0;
}
this.gender = gender;
}
// 只提供 getter
public String getName() { return name; }
public int getAge() { return age; }
public char getGender() { return gender; }
// 行为
public void study() {
System.out.println(name + " 正在学习...");
}
}
五、封装的核心好处(一定要记住)
- 数据安全:外部不能随意修改(避免非法值)
- 隐藏实现细节:内部怎么存储、怎么计算,外部不需要知道
- 便于维护:内部改动不影响外部调用
- 提高可读性:通过方法名清晰表达意图(setAge 比直接 age= -5 有意义)
- 支持后续扩展:可以轻松加日志、校验、缓存、触发事件等
六、初学者最容易犯的错误总结
| 错误写法 | 问题 | 正确做法 |
|---|---|---|
| 所有属性都 public | 完全没有封装 | 改成 private + getter/setter |
| setter 没有任何校验 | 数据可能不合法 | 加 if 判断、范围检查 |
| 构造方法没写,全部靠 set 赋值 | 对象可能处于不完整状态 | 优先用构造函数初始化 |
| 属性名和参数名一样没写 this | 赋值失败(就近原则) | 记得写 this. |
| 直接访问 obj.age | 破坏封装 | 必须用 getAge() |
总结:一句话记住这三块内容
- 面向对象:用“对象”来模拟现实世界,对象 = 数据 + 行为
- 类与对象:类是模板,对象是实例;一个类可以创建多个对象
- 封装:把数据藏起来(private),通过方法(public)控制访问和修改
如果你已经把上面内容理解了,恭喜你已经迈过了 Java 面向对象最重要的一关!
想继续深入哪个部分?
- 构造方法、this、static 关键字
- 包(package)和访问权限控制(public/protected/default/private)
- Java 中的内存图(栈、堆、方法区)
- 常见面试题:对象创建过程、this 和 super 的区别
- 下一阶段:继承与多态初步认识
告诉我你的需求,我继续带你往前走!