一、类与对象的核心概念
在Java中,类(Class) 和对象(Object) 是面向对象编程(OOP)的核心,理解它们是掌握Java的基础。
1. 什么是类?
类是对一类事物的抽象描述,是一个“模板”或“蓝图”,定义了这类事物的属性(状态) 和方法(行为)。
- 例如:“汽车”是一个类,它的属性包括“颜色、品牌、排量”,方法包括“启动、加速、刹车”。
- 类不占用内存,它只是一种逻辑上的定义。
2. 什么是对象?
对象是类的具体实例,是真实存在的个体,基于类的模板创建,具有类定义的属性和方法。
- 例如:“我家那辆黑色的特斯拉Model 3”是“汽车”类的一个对象,它的属性有具体值(颜色=黑色,品牌=特斯拉,排量=纯电),可以执行启动、加速等行为。
- 对象占用内存,每个对象都是独立的。
3. 类与对象的关系
- 类是对象的“模板”,对象是类的“实例”。
- 一个类可以创建多个对象(如同一个模具可以生产多个零件)。
二、类的定义
类通过 class 关键字定义,包含成员变量(属性) 和成员方法(行为) 两部分。
1. 类的定义语法
修饰符 class 类名 {
// 成员变量(属性):描述类的状态
数据类型 变量名1;
数据类型 变量名2;
// 成员方法(行为):描述类的操作
修饰符 返回值类型 方法名(参数列表) {
方法体;
}
}
- 修饰符:常用
public(公开,任何地方可访问)或默认(仅同包可访问)。 - 类名:遵循“大驼峰命名法”(如
Person、Car),首字母大写。
2. 成员变量(属性)
成员变量是类中定义的变量,用于存储对象的状态,每个对象的成员变量值可以不同。
- 例如:
Person类的name(姓名)、age(年龄)。
3. 成员方法(行为)
成员方法是类中定义的函数,用于描述对象的行为,可操作成员变量或执行特定功能。
- 例如:
Person类的eat()(吃饭)、study()(学习)。
示例:定义一个 Person 类
// 定义Person类(描述“人”这一类事物)
public class Person {
// 成员变量(属性):姓名、年龄、性别
String name; // 姓名
int age; // 年龄
char gender; // 性别('男'/'女')
// 成员方法(行为):说话
public void speak() {
// 方法体:打印个人信息
System.out.println("我叫" + name + ",今年" + age + "岁,性别" + gender);
}
// 成员方法:吃饭
public void eat(String food) {
System.out.println(name + "正在吃" + food);
}
}
三、对象的创建与使用
对象通过 new 关键字基于类创建,步骤为:声明对象变量 → 创建对象 → 访问属性和方法。
1. 创建对象的语法
// 格式:类名 对象名 = new 类名();
Person p1 = new Person(); // 基于Person类创建一个对象p1
new Person():在内存(堆)中创建一个Person类型的对象,并调用类的构造方法初始化。Person p1:在内存(栈)中声明一个引用变量p1,指向堆中创建的对象。
2. 访问对象的属性和方法
通过 . 操作符 访问对象的成员变量和成员方法:
- 访问属性:
对象名.属性名 - 调用方法:
对象名.方法名(参数)
示例:使用 Person 类创建对象并操作
public class TestPerson {
public static void main(String[] args) {
// 1. 创建第一个Person对象p1
Person p1 = new Person();
// 2. 给p1的属性赋值
p1.name = "张三";
p1.age = 20;
p1.gender = '男';
// 3. 调用p1的方法
p1.speak(); // 输出:我叫张三,今年20岁,性别男
p1.eat("米饭"); // 输出:张三正在吃米饭
// 4. 创建第二个Person对象p2(属性值不同)
Person p2 = new Person();
p2.name = "李四";
p2.age = 18;
p2.gender = '女';
p2.speak(); // 输出:我叫李四,今年18岁,性别女
p2.eat("面条"); // 输出:李四正在吃面条
}
}
四、构造方法(初始化对象)
构造方法是创建对象时自动调用的特殊方法,用于初始化对象的属性(给成员变量赋初始值)。
1. 构造方法的特点
- 方法名必须与类名完全相同(包括大小写)。
- 没有返回值(连
void都不能写)。 - 不能被
static、final等修饰符修饰。 - 创建对象时通过
new 类名(参数)自动调用。
2. 构造方法的分类
- 无参构造方法:没有参数的构造方法。
- 若类中未定义任何构造方法,Java会自动生成一个默认的无参构造(空方法体)。
- 有参构造方法:带参数的构造方法,用于创建对象时直接给属性赋值。
3. 构造方法的定义与使用
public class Person {
String name;
int age;
char gender;
// 1. 无参构造方法(手动定义,避免默认构造被覆盖)
public Person() {
// 初始化默认值(可选)
name = "未知";
age = 0;
gender = '?';
}
// 2. 有参构造方法(给name和age赋值)
public Person(String n, int a) {
name = n;
age = a;
gender = '?'; // 性别默认未知
}
// 3. 有参构造方法(给所有属性赋值)
public Person(String n, int a, char g) {
name = n;
age = a;
gender = g;
}
// 成员方法
public void speak() {
System.out.println("我叫" + name + ",今年" + age + "岁,性别" + gender);
}
}
示例:通过构造方法创建对象
public class TestConstructor {
public static void main(String[] args) {
// 调用无参构造:属性使用默认值
Person p1 = new Person();
p1.speak(); // 输出:我叫未知,今年0岁,性别?
// 调用两个参数的构造
Person p2 = new Person("王五", 25);
p2.speak(); // 输出:我叫王五,今年25岁,性别?
// 调用三个参数的构造
Person p3 = new Person("赵六", 30, '男');
p3.speak(); // 输出:我叫赵六,今年30岁,性别男
}
}
五、封装(面向对象核心特性)
封装是指隐藏对象的属性和实现细节,仅通过公共方法对外暴露接口,目的是保护数据安全,控制访问权限。
1. 封装的实现步骤
- 步骤1:用
private修饰成员变量(私有属性,仅本类可直接访问)。 - 步骤2:提供
public的 getter方法(获取属性值)和 setter方法(修改属性值),在方法中可添加逻辑校验。
示例:封装 Person 类
public class Person {
// 1. 私有成员变量(仅本类可访问)
private String name; // 姓名
private int age; // 年龄(年龄应≥0)
private char gender; // 性别
// 2. 无参构造
public Person() {}
// 3. 有参构造(通过setter赋值,复用校验逻辑)
public Person(String name, int age, char gender) {
setName(name);
setAge(age);
setGender(gender);
}
// 4. getter方法:获取name
public String getName() {
return name;
}
// 5. setter方法:设置name(可加校验,如非空)
public void setName(String name) {
if (name == null || name.trim().isEmpty()) {
this.name = "默认姓名"; // 非法值时设默认
} else {
this.name = name;
}
}
// 6. getter方法:获取age
public int getAge() {
return age;
}
// 7. setter方法:设置age(校验年龄≥0)
public void setAge(int age) {
if (age < 0) {
this.age = 0; // 非法年龄设为0
} else {
this.age = age;
}
}
// 8. getter和setter for gender(简化)
public char getGender() {
return gender;
}
public void setGender(char gender) {
this.gender = gender;
}
public void speak() {
System.out.println("我叫" + name + ",今年" + age + "岁,性别" + gender);
}
}
示例:使用封装后的 Person 类
public class TestEncapsulation {
public static void main(String[] args) {
Person p = new Person();
// 不能直接访问私有属性(编译报错):p.age = -5;
// 通过setter设置属性(自动触发校验)
p.setName(""); // 空字符串 → 被setName()处理为"默认姓名"
p.setAge(-5); // 负数年龄 → 被setAge()处理为0
p.setGender('女');
p.speak(); // 输出:我叫默认姓名,今年0岁,性别女
// 通过有参构造创建对象(同样触发校验)
Person p2 = new Person(null, -10, '男');
p2.speak(); // 输出:我叫默认姓名,今年0岁,性别男
}
}
六、this 关键字
this 代表当前对象的引用,用于区分成员变量和局部变量,或调用本类的其他构造方法。
1. this 的常用场景
-
场景1:当成员变量与局部变量同名时,用
this.成员变量表示成员变量。public void setName(String name) { // 局部变量name与成员变量同名 this.name = name; // this.name → 成员变量;name → 局部变量 } -
场景2:在构造方法中调用本类的其他构造方法(必须放在构造方法的第一行)。
public Person() { System.out.println("调用了无参构造"); } public Person(String name) { this(); // 调用本类的无参构造(必须在第一行) this.name = name; } -
场景3:作为方法的返回值,返回当前对象(支持链式调用)。
public Person setAge(int age) { this.age = age; return this; // 返回当前对象 } // 链式调用 p.setName("张三").setAge(20).setGender('男');
七、类与对象的内存模型(补充理解)
-
对象的内存分配:
- 成员变量:存储在堆内存中(每个对象的成员变量独立存储)。
- 成员方法:存储在方法区中(所有对象共享同一方法代码,仅存储一份)。
- 引用变量(如
p1):存储在栈内存中,指向堆中的对象。
-
例如:
Person p1 = new Person(); p1.name = "张三";- 堆内存中创建
Person对象,name被赋值为“张三”。 - 栈内存中
p1存储对象的地址(引用)。
- 堆内存中创建
八、总结
- 类是抽象模板,定义属性和方法;对象是类的具体实例,占用内存。
- 对象通过
new关键字创建,通过.操作符访问属性和方法。 - 构造方法用于初始化对象,无参构造默认存在,有参构造需手动定义。
- 封装通过
private隐藏属性,提供getter/setter控制访问,保证数据安全。 this关键字代表当前对象,用于区分变量或调用构造方法。
类与对象是Java面向对象编程的基石,后续的继承、多态等特性均基于此,掌握它们是学习Java的关键。
添加习题链接
在文章末尾添加以下习题链接,读者点击可直接跳转到对应页面:

2363

被折叠的 条评论
为什么被折叠?



