Java 类与对象

该文章已生成可运行项目,

一、类与对象的核心概念

在Java中,类(Class)对象(Object) 是面向对象编程(OOP)的核心,理解它们是掌握Java的基础。

1. 什么是类?

类是对一类事物的抽象描述,是一个“模板”或“蓝图”,定义了这类事物的属性(状态)方法(行为)

  • 例如:“汽车”是一个类,它的属性包括“颜色、品牌、排量”,方法包括“启动、加速、刹车”。
  • 类不占用内存,它只是一种逻辑上的定义。
2. 什么是对象?

对象是类的具体实例,是真实存在的个体,基于类的模板创建,具有类定义的属性和方法。

  • 例如:“我家那辆黑色的特斯拉Model 3”是“汽车”类的一个对象,它的属性有具体值(颜色=黑色,品牌=特斯拉,排量=纯电),可以执行启动、加速等行为。
  • 对象占用内存,每个对象都是独立的。
3. 类与对象的关系
  • 类是对象的“模板”,对象是类的“实例”。
  • 一个类可以创建多个对象(如同一个模具可以生产多个零件)。

二、类的定义

类通过 class 关键字定义,包含成员变量(属性)成员方法(行为) 两部分。

1. 类的定义语法
修饰符 class 类名 {
    // 成员变量(属性):描述类的状态
    数据类型 变量名1;
    数据类型 变量名2;
    
    // 成员方法(行为):描述类的操作
    修饰符 返回值类型 方法名(参数列表) {
        方法体;
    }
}
  • 修饰符:常用 public(公开,任何地方可访问)或默认(仅同包可访问)。
  • 类名:遵循“大驼峰命名法”(如 PersonCar),首字母大写。
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 都不能写)。
  • 不能被 staticfinal 等修饰符修饰。
  • 创建对象时通过 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:提供 publicgetter方法(获取属性值)和 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 存储对象的地址(引用)。

八、总结

  1. 是抽象模板,定义属性和方法;对象是类的具体实例,占用内存。
  2. 对象通过 new 关键字创建,通过 . 操作符访问属性和方法。
  3. 构造方法用于初始化对象,无参构造默认存在,有参构造需手动定义。
  4. 封装通过 private 隐藏属性,提供 getter/setter 控制访问,保证数据安全。
  5. this 关键字代表当前对象,用于区分变量或调用构造方法。

类与对象是Java面向对象编程的基石,后续的继承、多态等特性均基于此,掌握它们是学习Java的关键。

添加习题链接

在文章末尾添加以下习题链接,读者点击可直接跳转到对应页面:

点击此处查看习题

本文章已经生成可运行项目
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值