Java类与对象(掌握面向对象的核心)

从C语言入门编程人,刚接触Java时一定会有个疑问:struct 已经能定义复合数据类型了,为什么Java还要提出 class、类与对象的概念?

实际上这是两种完全不同的编程思维范式。

c语言是面向过程语言,面向过程的核心是过程,也就是 “步骤、流程”。它把一个问题拆解成「先做什么、再做什么、最后做什么」,用一个个函数去实现每个步骤,最后按顺序调用函数完成任务。

在“面向对象程序设计(Object-Oriented Programming, OOP)里。面向对象的核心是对象,也就是 “实体、角色”。它先不着急想步骤,而是先分析:这件事里有哪些 “事物” 参与?每个事物有什么特征(属性)、能做什么事(行为)?把属性和行为打包成一个 “对象”,再让对象之间互相配合完成任务。
类与对象不是Java凭空创造的语法,而是面向对象思想最基础的载体——它把“数据”和“操作数据的行为”打包在一起,让编程从“一步步怎么做”,变成了“让谁来做”。

一、类:面向对象的“抽象模板”

1. 什么是类?

在面向对象的世界观里,一切皆对象,而类(Class)就是对同一类事物的共性抽象

  • 从语法角度:类是Java中自定义的引用数据类型,相当于我们自己定义了一种新的“数据类型”。
  • 从设计角度:类是一张设计图纸,定义了一类事物拥有的属性(成员变量)行为(成员方法)

对比C语言的 struct 你会立刻明白差异:C的结构体只能定义数据,而Java的类可以同时包含“数据”和“处理数据的方法”,这就是最基础的封装思想。

举个例子:我们要描述“学生”这类事物,就可以定义一个 Student 类:

public class Student {
    // 属性(成员变量):学生的共同特征
    private String name; // 姓名
    private int age;     // 年龄

    // 行为(成员方法):学生能做的事
    public void study() {
        System.out.println(name + "正在学习");
    }
}

这里的 nameage 是所有学生都有的属性,study() 是学生都有的行为;Student 这个类,就定义了“学生”这个群体的统一规范。

二、对象:类的“具体实例”

1. 什么是对象?

类是抽象的模板,不能直接使用;对象(Object)就是根据类这个模板,创建出来的具体、真实的实例。(相当于印钞机和纸币的关系),更精确的说对象就是真实世界中的实体,对象与实体是一一对应的,也就是说现实世界中每一个实体都是一个对象,它是一种具体的概念。

  • 类是“学生”这个概念,对象就是“名叫张三、今年18岁”的这个具体学生。
  • 一个类可以创建无数个对象,每个对象的属性值可以不同,但都遵循类定义的结构。

在Java中,我们用 new 关键字创建对象:

public class Main {
    public static void main(String[] args) {
        // 创建Student对象,变量s是对象的引用
        Student s = new Student();
    }
}

2. 基本类型 vs 引用类型

这里要区分一个核心概念:Java的数据类型分为两类,这也是理解对象的关键:

类型 存储内容 存储位置 示例
基本数据类型 具体的数值 栈内存 int a = 10;
引用数据类型 对象的内存地址(引用) 栈里存地址,对象本体在堆内存 String str = "Hello"; Student s = new Student();

简单说:int a = 10 里,变量a和值10都在栈里;而 Student s 里,变量s只是一个“地址指针”存在栈中,真正的学生对象本体,存在堆内存里。

三、深入底层:对象的内存模型

很多人学不懂对象,是因为没搞懂栈(Stack)和堆(Heap)的分工。我们结合内存模型拆解 new Student() 的全过程。

1. 栈与堆的分工

  • 栈内存(Stack):遵循“先入后出”的规则,存放方法的局部变量、方法调用的栈帧。方法执行结束,栈帧自动销毁,内存自动释放。
  • 堆内存(Heap):存放所有new出来的对象本体,内存空间大,不会随方法结束自动销毁。

2. 对象创建的内存过程

当执行 Student s = new Student(); 时:

  1. JVM在堆内存中开辟一块空间,创建Student对象,给成员变量赋默认初始值(引用类型默认null,int默认0);
  2. 将这个对象的内存地址,赋值给栈内存中的变量 s
  3. 后续我们操作变量 s,本质是通过地址找到堆里的对象,这就是Java的**引用(Reference)**机制。

3. 和C语言的对比:自动垃圾回收(GC)

在C语言中,我们手动用 malloc 申请堆内存,用完必须手动 free 释放,否则就会出现内存泄漏。
而在Java中,你不需要手动释放内存——JVM的垃圾回收器(GC)会自动回收没有任何引用指向的堆对象。当一个对象没有任何栈变量指向它时,GC就会在合适的时机回收它的内存,彻底解放了程序员的内存管理负担。

四、对象的“出生”:构造方法

对象创建出来时,成员变量默认都是初始值(0、null等)。如果我们想在创建对象的同时就给属性赋值,就需要用到构造方法(Constructor)

1. 构造方法的特点

  • 方法名必须和类名完全一致;
  • 没有返回值类型(连void都不能写);
  • 在创建对象(new)时自动调用,专门用来做对象的初始化。

2. 无参构造与有参构造

  • 无参构造方法:如果你在类里一个构造方法都不写,编译器会默认给你生成一个空的无参构造。
  • 有参构造方法:我们自己定义带参数的构造方法,在创建对象时传入参数,给成员变量赋值。

还是用Student类举例:

public class Student {
    private String name;
    private int age;

    // 1. 无参构造方法(默认提供,也可以手动写)
    //但最好还是写,因为它有独特的作用
    public Student() {
    }

    // 2. 有参构造方法:创建对象时直接赋值
    public Student(String name, int age) {
        // this关键字:指代当前正在创建的对象
        // 区分成员变量和局部变量
        this.name = name;
        this.age = age;
    }
}

创建对象时就可以直接赋值:

// 调用有参构造,创建对象同时赋值
Student zhangsan = new Student("张三", 18);

这里的 this 关键字,代表“当前对象”,它主要作用就是区分同名的成员变量和局部变量。
而之所以要有this代表“当前对象”,是因为方法是对象才能调用的。相当于得先有人(对象),然后人要有吃饭的行为(方法),最后人才可以执行吃饭的行为(方法),不然没有对象那谁来执行方法呢?所以方法必须在类里面,也必须由类生成对象来执行。搞清关系就好理解面向-对象的含义了。

五、封装:面向对象的核心思想体现

讲到这里,你可能会问:为什么要把 nameageprivate 修饰?为什么不直接设为public让外部随便访问?
这就涉及到面向对象三大特性之首——封装

1. 封装的思想

封装的核心是:隐藏内部实现细节,对外暴露可控的访问入口

  • private 修饰成员变量,让外部不能直接读写属性;
  • 提供 public 修饰的 getXxx / setXxx 方法,让外部只能通过我们指定的方法访问属性。

这样做的好处是什么?我们可以在方法里加入数据校验,保证数据的合法性。比如年龄不能是负数:

public void setAge(int age) {
    if (age >= 0 && age <= 120) {
        this.age = age;
    } else {
        System.out.println("年龄不合法");
    }
}

如果属性是public,外部随便赋值一个负数,程序就会出现逻辑错误;而封装之后,所有修改都必须经过我们的校验,数据安全性大大提升。
简单来说有了对象后,我们还要运用对象来勾勒或者说完成对现实问题的解答,而有些对象的特征和行为(变量和方法)是不变的,如果没有private的来约束或者说封装的话那不经意的改变都会使得对象缺胳膊少腿、忘记吃饭睡觉,又或者随意改动账号,这不利于我们使用以及对代码的安全和维护。

六、面向对象的优势

理解了类与对象、封装,我们再回头看面向对象和面向过程的区别:

  • 面向过程(C语言为代表):思考的是“步骤”——先做什么,再做什么,函数是最小单位,适合解决简单、线性的问题。
  • 面向对象(Java为代表):思考的是“实体”——有哪些角色,每个角色有什么属性、能做什么,类/对象是最小单位。

当软件规模越来越大、需求越来越复杂时,面向对象的优势就会凸显:

  1. 模块化:每个类负责一个职责,代码结构清晰,便于维护;
  2. 复用性:一个类可以创建无数个对象,也可以被其他地方复用;
  3. 扩展性:基于类的继承、多态特性,可以在不修改原有代码的前提下扩展功能。

而这一切的基础,就是类与对象。

更多推荐