Java 面向对象:类、对象与封装
类是对象的模板,对象是内存中的实体。本篇讲透”定义类、创建对象、访问成员”这条主线,用内存布局说清栈、堆、方法区的分工,再落到封装、private 与 this 这三个最易含糊的概念上。
本篇目标
- 说清类与对象的关系,能独立写出标准类
- 描述
new Student()执行后的内存布局 - 分清成员变量与局部变量的区别
- 理解封装动机,会用 private + getter/setter,明白 this 指向谁
从面向过程到面向对象
面向过程关注”第一步做什么、第二步做什么”,自己动走完全部流程;面向对象先问”这件事该由谁来做”,把数据和行为装进对象,再指挥对象协作。洗衣服:面向过程是”接水、加洗衣粉、搓洗、晾晒”一步步来;面向对象是找到”洗衣机”对象,调用它的洗涤方法。角色从执行者变成指挥者,复杂的事被拆给不同对象去办——面向对象开发就是不断创建对象、使用对象、指挥对象做事,这片土壤上长出封装、继承、多态三大特征。
类与对象:模板与实例
现实事物用”属性 + 行为”描述:属性是名词,行为是动词。Java 用 class 描述事物,成员变量对应属性,成员方法对应行为。类是一组相关属性和行为的集合,是抽象的模板;对象是模板造出的具体个体。”学生”是类,”坐在第三排的张三”才是对象。
class Student { |
使用就三步:类名 对象名 = new 类名();,然后 对象名.变量名、对象名.方法名()。初学阶段可以在一个 .java 文件里写两个类——一个被描述的类、一个含 main 的测试类,文件名与测试类保持一致即可。常见错误:习惯性给成员方法加 static——加了它就属于类而不属于对象,访问不了成员变量,原因下篇揭晓。
对象创建时的内存分配
Student s = new Student(); 背后,JVM 三块内存各司其职:
| 内存区域 | 存什么 | 本例内容 |
|---|---|---|
| 方法区 | 类的字节码信息 | Student.class 的字段与方法描述 |
| 堆 | new 出的对象 | 实例,name=null、age=0 |
| 栈 | 方法的局部变量 | 引用 s,保存对象地址 |
顺序:Student.class 进方法区;main 进栈并声明引用 s;new 在堆中开辟对象、字段拿默认值;构造方法进栈赋值后弹栈;地址交给 s。口诀:”栈中存引用,堆中存对象”。再写 Student s2 = s;,堆里不会多对象,只是栈中多一个指向同一地址的引用——“三个引用两个对象”的内存图说的就是它:通过 s2 改字段,用 s 看同样变。
成员变量与局部变量
| 维度 | 成员变量 | 局部变量 |
|---|---|---|
| 定义位置 | 类中、方法外 | 方法内或形参上 |
| 内存位置 | 堆(随对象) | 栈(随方法) |
| 生命周期 | 随对象创建而生、消失而亡 | 随方法调用而生、弹栈而亡 |
| 初始值 | 有默认值(0、null、false) | 无默认值,必须先赋值 |
同名时方法内就近取值,想访问成员变量必须加 this。引用类型(数组、类、接口、枚举)作形参时传的是对象地址。
匿名对象
new Student().study(); 这种没有引用接住的对象就是匿名对象。两个适用场景:方法只调一次,省一行声明;作为实参传递,如 print(new Student());——看到形参是类类型,就要明白它需要的是该类的对象。注意:匿名对象用完即成垃圾,等垃圾回收器处理,要操作两次以上必须给它名字。
封装与 private
直接把 age 暴露出去,调用方写 s.age = -20; 编译器不拦——语法合法,逻辑荒谬。封装就是隐藏对象的属性和实现细节,仅对外提供受控的公共访问方式:字段用 private 私有化,再提供 getXxx/setXxx,在 setter 里加校验。private 是权限修饰符,被它修饰的成员只能在本类中访问。好处:隐藏细节、提高复用、保证安全。注意 private 只是封装的一种体现,方法、类本身也是封装,完整的权限图景要等学到”包”。时代化一句:今天 getter/setter 常由 Lombok 注解或 record 关键字自动生成,但”字段私有、受控访问”的封装思想从没变过。
this 的作用
this 代表当前对象的引用——谁调用这个方法,this 就是谁。最常见用途是解决 setter 重名:
public void setAge(int age) { |
没有 this,age = age 按就近原则只是把参数赋给自己,成员变量纹丝不动。getter 里 return this.age; 的 this 可省略,系统默认补上。此外 this 还能以 this(...) 的形式在构造方法里调用本类其他构造,留待构造方法一篇展开。
经典练习:标准手机类
字段私有化、配齐 getter/setter、用 this 区分重名,就是标准 JavaBean:
class Phone { |
测试类里 Phone p = new Phone(); p.setBrand("三星");,体会”创建对象、指挥对象做事”。
小结
- 类是模板,对象是实例:属性写成员变量,行为写成员方法。
- 内存分工:方法区存类信息,堆存对象,栈存引用与局部变量;引用赋值只复制地址。
- 成员变量与局部变量差在位置、内存、生命周期、初始值;同名就近原则。
- 封装的落点是 private 字段 + 公共 get/set;this 是当前对象引用,用来区分重名变量。

