Skip to content

2026-08-27 · 类、对象、构造方法、static——OOP 的核心概念。

Java 面向对象基础

1. 面向对象思想

面向对象(OOP)是一种编程思想,核心是:把数据和操作数据的方法绑定在一起,封装成对象

对比面向过程(C 语言风格):

java
// 面向过程:数据和方法分开
int[] scores = {85, 90, 78};
double avg = calculateAvg(scores); // 数据传给方法

// 面向对象:数据和方法在一起
Student s = new Student("张三", 85);
s.display(); // 对象自己知道自己是谁、分数多少

OOP 三大特性:封装、继承、多态(后面逐步讲)。

2. 类与对象

= 模板(定义有什么属性和方法) 对象 = 实例(根据模板创建出来的具体东西)

java
// 定义类(模板)
public class Student {
    // 属性(成员变量)
    String name;
    int age;

    // 方法(行为)
    void study() {
        System.out.println(name + " 在学习");
    }
}

// 使用类(创建对象)
Student s1 = new Student();  // s1 是对象
s1.name = "张三";           // 给属性赋值
s1.age = 20;
s1.study();                 // 调用方法:张三 在学习

Student s2 = new Student();  // 可以创建多个对象
s2.name = "李四";
s2.study();                 // 李四 在学习

new 关键字创建对象,= 把对象赋给变量(引用)。s1s2 是引用变量,指向堆内存中的对象。

3. 匿名对象

创建对象时不赋给变量,直接使用:

java
// 普通对象
Student s = new Student();
s.study();

// 匿名对象(没有名字,用完就丢)
new Student().study();

// 匿名对象作为方法参数
printName(new Student("张三"));

匿名对象只能用一次(因为没有引用指向它,用完就被垃圾回收)。适合只调用一次的场景。

4. 成员变量 vs 局部变量

java
public class Demo {
    int a = 10;      // 成员变量(类里面、方法外面)

    void test() {
        int b = 20;  // 局部变量(方法里面)
        System.out.println(a); // ✅ 能访问成员变量
        System.out.println(b); // ✅ 能访问局部变量
    }

    void test2() {
        // System.out.println(b); // ❌ 不能访问另一个方法的局部变量
    }
}
区别成员变量局部变量
位置类里面,方法外面方法里面或代码块里
默认值有(0、null、false 等)没有,必须手动赋值
生命周期跟着对象走(对象存在就存在)跟着方法走(方法执行完就销毁)
访问权限类内任何地方都能用只在当前方法/块内能用

成员变量有默认值(不用赋初值就能用),局部变量没有(不赋值直接用编译报错)。

5. 构造方法

对象创建时自动调用的方法,用来初始化属性:

java
public class Student {
    String name;
    int age;

    // 空参构造(没有参数)
    public Student() {
        System.out.println("空参构造被调用了");
    }

    // 有参构造(带参数)
    public Student(String name, int age) {
        this.name = name;  // this.name 是成员变量,name 是参数
        this.age = age;
    }
}

// 使用
Student s1 = new Student();           // 调用空参构造
Student s2 = new Student("张三", 20); // 调用有参构造
System.out.println(s2.name);          // 张三

构造方法规则

  • 方法名和类名相同
  • 没有返回类型(连 void 都没有)
  • 创建对象时自动调用,不能手动调用

this 关键字

  • this.name = 当前对象的成员变量
  • name = 参数(或局部变量)
  • 当参数名和成员变量名相同时,用 this 区分

构造方法重载:同一个类可以有多个构造方法(参数不同),创建对象时自动匹配:

java
Student s1 = new Student();              // 调用空参
Student s2 = new Student("张三");        // 调用一个参数的
Student s3 = new Student("张三", 20);    // 调用两个参数的

如果不写任何构造方法,Java 会自动提供一个空参构造。但如果写了有参构造,就不会自动提供空参构造了(想用就自己写一个)。

6. static 关键字

static 修饰的内容属于类本身,不属于某个对象:

java
public class Student {
    String name;           // 成员变量(属于对象)
    static String school;  // 静态变量(属于类)

    void study() {         // 成员方法(属于对象)
        System.out.println(name + " 在学习");
    }

    static void show() {   // 静态方法(属于类)
        // System.out.println(name); // ❌ 静态方法不能访问非静态成员
        System.out.println(school); // ✅ 静态方法只能访问静态成员
    }
}

// 使用
Student.school = "北京大学"; // 通过类名直接访问(不需要创建对象)
Student.show();              // 通过类名直接调用

Student s = new Student();
s.name = "张三";
// s.school = "北京大学";  // 也能通过对象访问,但不推荐(语义不清晰)

static 使用场景

  • 常量:static final String SCHOOL = "北京大学";
  • 工具方法:Math.random()Integer.parseInt() 都是 static
  • 计数器:static int count; 统计创建了多少个对象

static 注意事项

  • 静态方法不能直接访问非静态成员(成员变量、成员方法)
  • 非静态方法可以访问静态成员
  • 静态方法不能使用 this(因为 this 指向对象,静态方法没有对象)

7. 代码块

三种代码块,用于初始化:

构造代码块(实例初始化块)

java
public class Student {
    {
        System.out.println("构造代码块执行了");
    }

    public Student() {
        System.out.println("构造方法执行了");
    }
}

new Student();
// 输出:
// 构造代码块执行了
// 构造方法执行了

构造代码块在每个构造方法之前执行,适合多个构造方法的公共初始化逻辑。

静态代码块

java
public class Config {
    static {
        System.out.println("静态代码块执行了");
        // 可以做复杂的初始化,比如读配置文件、建立数据库连接
    }
}

new Config();  // 第一次使用时执行
new Config();  // 不会再执行(只执行一次)

静态代码块在类第一次被加载时执行,且只执行一次。适合静态资源的初始化。

执行顺序

java
public class Demo {
    static { System.out.println("1. 静态代码块"); }
    { System.out.println("2. 构造代码块"); }
    public Demo() { System.out.println("3. 构造方法"); }
}

new Demo();
// 输出:
// 1. 静态代码块(类加载时,只一次)
// 2. 构造代码块(每次创建对象)
// 3. 构造方法(每次创建对象)

记忆:静态 → 构造代码块 → 构造方法,这是固定的执行顺序。

数组里放对象(引用类型):

java
Student[] students = new Student[3]; // 创建一个长度为3的数组,每个元素是 null

// 逐个创建对象赋值
students[0] = new Student("张三", 20);
students[1] = new Student("李四", 21);
students[2] = new Student("王五", 22);

// 遍历
for (Student s : students) {
    System.out.println(s.name + " " + s.age);
}

对象数组里存的是引用(地址),不是对象本身。和基本类型数组(存值)不一样。