Java入门必学:类与对象的核心概念与实战应用
在Java编程世界中,“类与对象”是面向对象编程(OOP)的基石,也是从面向过程思维转向面向对象思维的关键。本文将结合实战代码,从概念定义、代码实现、内存模型到核心知识点,全方位拆解类与对象的使用逻辑,帮助初学者快速上手。
一、先搞懂:类与对象到底是什么?
1. 核心概念
- 类:本质是对象的“设计图”或“模板”,描述了某一类事物的共同特征(属性)和行为(方法)。比如“学生类”定义了所有学生都有的姓名、成绩等属性,以及计算总分、平均分等行为;“手机类”定义了手机的品牌、价格等属性,以及打电话、玩游戏等行为。
- 对象:是类的“具体实例”,是真实存在的事物。比如根据“学生类”创建出“播妞”“播仔”这两个具体的学生对象,每个对象都有自己独特的属性值,但共享类的行为方法;根据“手机类”创建出“小米手机”“苹果手机”等具体对象。
2. 关键原则
Java中必须先设计类,再创建对象——就像先画好建筑图纸,才能盖出具体的房子;先制定手机的设计方案,才能生产出一部部实际的手机。
二、实战:如何定义类与创建对象?
1. 定义类的规范格式
一个标准的Java类(Javabean类,专门用于封装属性和行为)包含成员变量(属性,通常是名词)和成员方法(行为,通常是动词),结构如下:
public class 类名 {
// 成员变量(属性):描述事物的特征
数据类型 变量名;
// 成员方法(行为):描述事物能执行的操作
public void 方法名() {
// 方法体:行为的具体实现逻辑
}
}
2. 经典示例:学生类的设计与使用
步骤1:定义学生类(Javabean类)
该类封装了学生的“姓名”“语文成绩”“数学成绩”等属性,以及“计算总成绩”“计算平均分”两种行为:
package com.wmh.object;
// 学生类:封装学生的属性与行为
public class Student {
// 成员变量(属性)
String name; // 学生姓名
double chinese; // 语文成绩
double math; // 数学成绩
// 成员方法(行为):打印总成绩
public void printAllscore() {
System.out.println(name + "总成绩是:" + (chinese + math));
}
// 成员方法(行为):打印平均分
public void printAvgscore() {
System.out.println(name + "平均成绩是:" + (chinese + math) / 2);
}
}
步骤2:创建对象并使用(测试类)
创建对象的核心格式:类名 对象名 = new 类名();
使用对象的两种核心操作:
- 访问属性:通过
对象名.成员变量给属性赋值或获取属性值; - 调用方法:通过
对象名.方法名()执行类中定义的行为。
package com.wmh.object;
// 测试类:创建学生对象并测试属性与方法
public class Test2 {
public static void main(String[] args) {
// 1. 创建第一个学生对象:播妞
Student s1 = new Student();
// 给对象的属性赋值
s1.name = "播妞";
s1.chinese = 100;
s1.math = 100;
// 调用对象的方法
s1.printAllscore(); // 输出结果:播妞总成绩是:200.0
s1.printAvgscore(); // 输出结果:播妞平均成绩是:100.0
// 2. 创建第二个学生对象:播仔
Student s2 = new Student();
s2.name = "播仔";
s2.chinese = 50;
s2.math = 100;
s2.printAllscore(); // 输出结果:播仔总成绩是:150.0
s2.printAvgscore(); // 输出结果:播仔平均成绩是:75.0
}
}
3. 其他实战案例:从“模板”到“实例”的延伸
类与对象的逻辑可复用在任何事物的抽象中,以下是两个常见场景的实现:
案例1:手机类的设计与使用
- 类的定义:抽象手机的“品牌”“价格”属性,以及“打电话”“玩游戏”行为;
- 对象创建:基于手机类创建“小米手机”“苹果手机”等具体实例。
// 手机类(Javabean类)
public class Phone {
// 属性
String brand; // 手机品牌
double price; // 手机价格
// 行为:打电话
public void call() {
System.out.println("手机在打电话");
}
// 行为:玩游戏
public void playGame() {
System.out.println("手机在玩游戏");
}
}
// 手机类测试类
public class PhoneTest {
public static void main(String[] args) {
// 创建第一个手机对象:小米手机
Phone p1 = new Phone();
p1.brand = "小米";
p1.price = 1999.98;
System.out.println("手机品牌:" + p1.brand + ",价格:" + p1.price);
p1.call(); // 输出:手机在打电话
// 创建第二个手机对象:苹果手机
Phone p2 = new Phone();
p2.brand = "苹果";
p2.price = 8999;
System.out.println("手机品牌:" + p2.brand + ",价格:" + p2.price);
p2.playGame(); // 输出:手机在玩游戏
}
}
案例2:女朋友类的设计与使用
- 类的定义:抽象“姓名”“年龄”“性别”属性,以及“吃饭”“睡觉”行为;
- 对象创建:创建“小诗诗”“小丹丹”两个具体对象并测试。
// 女朋友类(Javabean类)
public class GirlFriend {
// 属性
String name; // 姓名
int age; // 年龄
String gender; // 性别
// 行为:睡觉
public void sleep() {
System.out.println("女朋友在睡觉");
}
// 行为:吃饭
public void eat() {
System.out.println("女朋友在吃饭");
}
}
// 女朋友类测试类
public class GirlFriendTest {
public static void main(String[] args) {
// 创建第一个对象:小诗诗
GirlFriend gf1 = new GirlFriend();
gf1.name = "小诗诗";
gf1.age = 18;
gf1.gender = "萌妹子";
System.out.println(gf1.name + "," + gf1.age + "岁," + gf1.gender);
gf1.sleep(); // 输出:女朋友在睡觉
// 分割线
System.out.println("===================================");
// 创建第二个对象:小丹丹
GirlFriend gf2 = new GirlFriend();
gf2.name = "小丹丹";
gf2.age = 19;
gf2.gender = "萌妹子";
System.out.println(gf2.name + "," + gf2.age + "岁," + gf2.gender);
gf2.eat(); // 输出:女朋友在吃饭
}
}
三、深入理解:对象的内存模型
要真正掌握类与对象,必须搞懂其内存分配逻辑——Java会将数据分配到不同的内存区域,各司其职。JDK8及以后,Java内存主要分为栈、堆、元空间三大核心区域。
1. 核心内存区域分工
| 内存区域 | 存储内容 | 关键特点 |
|---|---|---|
| 栈 | 局部变量(如测试类中的对象名s1、p1、gf1) | 只保存对象的“地址值”,内存随方法调用创建、方法结束释放 |
| 堆 | 对象的具体属性值(如s1的name=“播妞”、chinese=100) | 每个对象占用独立空间,属性值可修改,内存需垃圾回收 |
| 元空间 | 类的结构信息(如学生类的成员变量定义、方法代码) | 所有对象共享同一类信息,类加载时初始化 |
2. 一个对象的创建流程(以Student s = new Student();为例)
- 加载类信息:Java虚拟机(JVM)将学生类的结构信息(属性、方法定义)加载到元空间;
- 声明局部变量:在栈中创建局部变量
s,此时s尚未指向任何对象; - 开辟堆空间:在堆中为新对象开辟一块内存,存储学生类的属性,并赋予默认值(如name=null、chinese=0.0);
- 显式赋值:若代码中给属性赋值(如
s.name=“播妞”),则更新堆中对应属性的值; - 绑定地址:将堆中对象的地址值(如“001”)赋值给栈中的变量
s,此时s通过地址指向堆中的对象; - 调用方法:当执行
s.printAllscore()时,JVM通过s的地址找到堆中对象,再去元空间执行学生类的printAllscore()方法代码。
3. 两个关键内存特性
特性1:两个对象——独立空间,互不影响
当创建两个对象(如s1和s2)时,堆中会开辟两块独立的内存空间,栈中两个变量保存不同的地址值。修改s1的属性值(如s1.math=90),只会改变s1对应的堆空间数据,不会影响s2。
特性2:两个引用指向同一个对象——共享空间,同步修改
若通过Student s2 = s1;让s2指向s1的地址,则s1和s2共享堆中同一块空间。此时修改s2.name=“新名字”,s1.name也会同步变成“新名字”——因为两者指向的是同一个对象。
四、必记知识点:变量与数据类型区别
1. 成员变量 vs 局部变量
成员变量(类中、方法外)和局部变量(方法内或方法参数)是Java中两种核心变量,区别如下:
| 区别维度 | 成员变量 | 局部变量 |
|---|---|---|
| 定义位置 | 类中,方法外部 | 方法内部,或方法的参数列表中 |
| 初始化值 | 有默认值(按数据类型分配,如int=0、String=null) | 无默认值,必须手动赋值后才能使用 |
| 内存位置 | 堆内存(随对象存储) | 栈内存(随方法存储) |
| 生命周期 | 随对象创建而存在,随对象被垃圾回收而消失 | 随方法调用而创建,随方法执行结束而释放 |
| 作用域 | 整个类中有效(所有非静态方法可访问) | 仅在当前方法中有效 |
2. 基本数据类型 vs 引用数据类型
Java数据类型分为两类,其核心区别在于内存存储方式:
| 类型分类 | 包含类型 | 存储方式 | 赋值特点 |
|---|---|---|---|
| 基本数据类型 | int、double、boolean、byte等 | 数据直接存储在变量所在的栈空间 | 赋值时传递“真实数据”(如int a=5; int b=a;,b存储的是5) |
| 引用数据类型 | 类(如Student、Phone)、数组、String | 变量存储地址(栈),数据存储在堆 | 赋值时传递“地址值”(如Student s2=s1;,s2存储的是s1的地址) |
3. this关键字的作用
当方法参数名与成员变量名相同时,需要用this关键字区分——this的本质是“当前方法调用者的地址值”,代表当前对象。
示例:
public class Student {
String name; // 成员变量
// 方法参数名与成员变量名相同,用this区分
public void setName(String name) {
this.name = name; // this.name:成员变量;name:方法参数(局部变量)
}
}
当调用s1.setName(“播妞”)时,this就代表s1的地址,最终将“播妞”赋值给s1的name属性。
五、类的定义规范与注意事项
- 命名规范:类名首字母大写,采用驼峰命名法(如
GirlFriend而非girlfriend或Girlfriend),且“见名知意”(如Student代表学生,Phone代表手机); - 文件与类的关系:一个Java文件中可定义多个类,但最多只能有一个类用
public修饰,且public修饰的类名必须与文件名完全一致(如文件名为Student.java,则public类名必须是Student); - Javabean类规范:专门封装属性和行为的类(如
Student、Phone)不写main方法,main方法应放在单独的测试类中(如Test2、PhoneTest); - 成员变量默认值:成员变量无需手动初始化,Java会按类型赋予默认值,具体如下:
| 数据类型分类 | 具体类型 | 默认值 |
|---|---|---|
| 基本类型(整数) | byte、short、int、long | 0 |
| 基本类型(浮点) | float、double | 0.0 |
| 基本类型(布尔) | boolean | false |
| 引用类型 | 类、接口、数组、String | null |
六、实战练习:自己设计一个类
掌握核心逻辑后,不妨动手实践——设计一个“汽车类”,要求如下:
- 包含属性:品牌(brand,String)、价格(price,double)、颜色(color,String);
- 包含行为:启动(start,打印“汽车启动”)、行驶(run,打印“汽车行驶中”);
- 创建两个对象:“宝马汽车”(品牌宝马,价格300000,颜色黑色)和“奔驰汽车”(品牌奔驰,价格400000,颜色白色),并调用两个行为。
参考实现:
// 汽车类(Javabean类)
public class Car {
// 属性
String brand;
double price;
String color;
// 行为:启动
public void start() {
System.out.println(brand + "(" + color + ")启动");
}
// 行为:行驶
public void run() {
System.out.println(brand + "(价格" + price + ")行驶中");
}
}
// 汽车类测试类
public class CarTest {
public static void main(String[] args) {
// 宝马汽车
Car bmw = new Car();
bmw.brand = "宝马";
bmw.price = 300000;
bmw.color = "黑色";
bmw.start(); // 输出:宝马(黑色)启动
bmw.run(); // 输出:宝马(价格300000.0)行驶中
// 奔驰汽车
Car benz = new Car();
benz.brand = "奔驰";
benz.price = 400000;
benz.color = "白色";
benz.start(); // 输出:奔驰(白色)启动
benz.run(); // 输出:奔驰(价格400000.0)行驶中
}
}
七、总结
类与对象是Java面向对象编程的“基石”,其核心逻辑可概括为三句话:
- 类是模板:定义事物的属性和行为,是抽象的“设计图”;
- 对象是实例:通过
new 类名()创建,持有独立的属性值,是具体的“事物”; - 内存是本质:栈存地址、堆存数据、元空间存类信息,理解内存模型才能真正掌握引用传递。
掌握类与对象后,后续的继承、多态、接口等面向对象特性都会迎刃而解。建议多尝试抽象生活中的事物(如书籍、动物、电器),通过编写类和创建对象的实战,逐步培养面向对象思维,为后续Java学习打下坚实基础。