面向对象编程(OOP)是 Java 语言的核心思想,它将现实世界中的事物抽象为 "类",通过封装、继承、多态等特性实现代码的复用与扩展。本文将系统梳理 Java 类及其成员、面向对象四大特征以及核心关键字的用法,帮助你构建完整的面向对象知识体系。

一、类与对象:OOP 的基石

1. 类的概念

类(Class)是对现实事物的抽象描述,包含事物的属性(是什么)和行为(能做什么)。例如 "猫" 可以抽象为Cat类,包含age(年龄)属性和run()(跑步)方法。

// 类的定义格式
修饰符 class 类名 {
    // 类的成员
}

2. 对象的概念

对象是类的具体实例,通过new关键字创建。一个类可以创建多个对象,每个对象拥有独立的属性值。

// 创建对象
Cat cat1 = new Cat(); // cat1是Cat类的一个对象
Cat cat2 = new Cat(); // cat2是Cat类的另一个对象

二、类的成员详解

1. 属性(成员变量)

属性是类中定义的变量,用于描述对象的状态。

分类:
  • 实例属性:属于对象,每个对象独立存储(默认值:数字 0/0.0、布尔 false、引用类型 null)
  • 静态属性:用static修饰,属于类,所有对象共享(后面详解static
public class Cat {
    // 实例属性(对象属性)
    public int age;        // 年龄
    private String name;   // 名字(私有属性)
    
    // 静态属性(类属性)
    public static String species = "哺乳动物"; // 所有猫都是哺乳动物
}
访问规则:
  • 实例属性:对象.属性名
  • 静态属性:类名.属性名(推荐)或对象.属性名(不推荐)

2. 方法(成员方法)

方法是类中定义的函数,用于描述对象的行为。

分类:
  • 实例方法:无static修饰,属于对象,可访问实例属性和静态属性
  • 静态方法:用static修饰,属于类,只能直接访问静态属性(后面详解static
public class Cat {
    // 实例方法
    public void eat(String food) {
        System.out.println("吃" + food);
    }
    
    // 静态方法
    public static void sleep() {
        System.out.println("猫在睡觉");
    }
}
方法重载(Overload):

同一类中,方法名相同但参数列表不同(个数 / 类型 / 顺序)的现象,与返回值无关。

// 方法重载示例
public class Calculator {
    // 整数相加
    public int add(int a, int b) {
        return a + b;
    }
    
    // 浮点数相加(参数类型不同,构成重载)
    public double add(double a, double b) {
        return a + b;
    }
    
    // 三个整数相加(参数个数不同,构成重载)
    public int add(int a, int b, int c) {
        return a + b + c;
    }
}

3. 构造方法

用于对象初始化的特殊方法,方法名与类名完全相同,无返回值

特点:
  • 若未定义构造方法,编译器自动生成无参构造方法
  • 若手动定义构造方法,默认无参构造会消失(如需使用需手动添加)
  • 创建对象时自动调用(new 类名(参数)
public class Cat {
    private String name;
    private int age;
    
    // 无参构造方法
    public Cat() {}
    
    // 有参构造方法(初始化属性)
    public Cat(String name, int age) {
        this.name = name; // this关键字后面详解
        this.age = age;
    }
}

// 使用构造方法创建对象
Cat cat = new Cat("小花", 3); // 调用有参构造

4. 代码块

{}包裹的代码片段,用于初始化操作。

分类:
  • 实例代码块:无static修饰,每次创建对象时执行(在构造方法前执行)
  • 静态代码块:用static修饰,类加载时执行(仅执行一次)
public class Cat {
    // 静态代码块(类加载时执行)
    static {
        System.out.println("Cat类加载了");
    }
    
    // 实例代码块(创建对象时执行)
    {
        System.out.println("创建了一个Cat对象");
    }
    
    // 构造方法
    public Cat() {
        System.out.println("执行构造方法");
    }
}

// 执行结果(第一次创建对象时):
// Cat类加载了
// 创建了一个Cat对象
// 执行构造方法

5. 内部类

定义在类内部的类,分为:

  • 成员内部类:类的成员位置定义,可访问外部类所有成员
  • 局部内部类:方法内部定义,仅在当前方法中有效
  • 匿名内部类:无类名的局部内部类,常用于简化接口实现
  • 静态内部类:用static修饰,只能访问外部类静态成员
public class Outer {
    private int num = 10;
    
    // 成员内部类
    class Inner {
        public void show() {
            System.out.println(num); // 访问外部类私有属性
        }
    }
    
    // 方法中使用内部类
    public void method() {
        // 局部内部类
        class LocalInner {
            public void print() {
                System.out.println("局部内部类");
            }
        }
        
        // 匿名内部类(实现Runnable接口)
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("匿名内部类实现线程");
            }
        };
    }
}

三、面向对象的四大特征

1. 封装(Encapsulation)

核心思想:隐藏对象的内部细节,仅通过公共接口对外暴露功能。

实现方式:
  • private修饰属性(隐藏细节)
  • 提供publicgetter/setter方法(暴露接口)
好处:
  • 保护数据安全(避免不合理赋值)
  • 提高代码可维护性(修改内部实现不影响外部调用)
public class Person {
    // 私有属性(隐藏)
    private int age;
    
    // getter方法(获取属性值)
    public int getAge() {
        return age;
    }
    
    // setter方法(设置属性值,可添加验证)
    public void setAge(int age) {
        if (age < 0 || age > 150) {
            throw new IllegalArgumentException("年龄必须在0-150之间");
        }
        this.age = age;
    }
}

2. 继承(Inheritance)

核心思想:子类继承父类的属性和方法,实现代码复用。

关键字:extends
// 父类(基类)
public class Animal {
    public void eat() {
        System.out.println("动物吃东西");
    }
}

// 子类(派生类)继承Animal
public class Cat extends Animal {
    // 继承父类的eat()方法
    public void catchMouse() {
        System.out.println("猫抓老鼠"); // 子类特有方法
    }
}
特点:
  • Java 单继承(一个类只能有一个直接父类)
  • 子类可访问父类非私有成员(public/protected
  • 方法重写(Override):子类重写父类方法,实现个性化逻辑
// 方法重写示例
@Override
public void eat() {
    System.out.println("猫吃鱼"); // 重写父类方法
}
重写规则:
  • 方法名、参数列表必须与父类相同
  • 返回值类型小于等于父类(协变返回)
  • 访问权限大于等于父类
  • 不能抛出比父类更多的异常

3. 多态(Polymorphism)

核心思想:同一行为,不同对象有不同实现("一个接口,多种方法")。

实现条件:
  1. 存在继承关系
  2. 子类重写父类方法
  3. 父类引用指向子类对象(向上转型)
// 多态示例
public class Demo {
    public static void main(String[] args) {
        Animal animal = new Cat(); // 父类引用指向子类对象
        animal.eat(); // 执行子类重写的方法(输出"猫吃鱼")
    }
}
好处:
  • 提高代码扩展性(新增子类不影响现有代码)
  • 实现解耦(面向抽象编程)

4. 接口(Interface)

接口是抽象方法的集合,用于定义规范("是什么,不关心怎么做")。

定义与实现:
// 接口定义(interface关键字)
public interface Flyable {
    // 抽象方法(默认public abstract)
    void fly();
    
    // JDK8+:默认方法(有实现)
    default void land() {
        System.out.println("降落");
    }
    
    // JDK8+:静态方法
    static void takeoff() {
        System.out.println("起飞");
    }
}

// 类实现接口(implements关键字)
public class Bird implements Flyable {
    @Override
    public void fly() {
        System.out.println("鸟用翅膀飞");
    }
}
特点:
  • 接口不能实例化
  • 一个类可实现多个接口(class A implements B, C
  • 接口可继承接口(支持多继承)
  • 接口中的属性默认是public static final(常量)

四、核心关键字解析

1. this

代表当前对象的引用,用于:

  • 区分成员变量和局部变量
  • 调用当前对象的方法
  • 调用当前类的其他构造方法(this(参数),必须在构造方法第一行
public class Person {
    private String name;
    
    public Person(String name) {
        this.name = name; // 区分成员变量和局部变量
    }
    
    public void print() {
        this.show(); // 调用当前对象的方法
    }
    
    public void show() {
        System.out.println(name);
    }
}

2.super

代表父类对象的引用,用于:

  • 访问父类的属性
  • 调用父类的方法
  • 调用父类的构造方法(super(参数),必须在子类构造方法第一行)
public class Cat extends Animal {
    public Cat() {
        super(); // 调用父类无参构造(默认隐含,可省略)
    }
    
    @Override
    public void eat() {
        super.eat(); // 调用父类的eat()方法
        System.out.println("猫吃鱼");
    }
}

3. static

用于修饰类级别的成员(不属于对象,属于类):

修饰属性:
  • 静态属性:所有对象共享,类加载时初始化
修饰方法:
  • 静态方法:可直接通过类名调用,不能访问非静态成员,不能用this/super
修饰代码块:
  • 静态代码块:类加载时执行,用于初始化静态资
public class Student {
    public static String schoolName; // 静态属性
    
    static {
        schoolName = "阳光小学"; // 静态代码块初始化
    }
    
    public static void showSchool() { // 静态方法
        System.out.println(schoolName);
    }
}

// 调用静态成员
Student.showSchool(); // 直接通过类名调用

4. final

表示 "最终的",可修饰:

  • :不能被继承(如String类)

final class FinalClass {} // 不能有子类

 方法:不能被重写

public class Parent {
    public final void method() {} // 子类不能重写
}

变量:变为常量(只能赋值一次)

final int MAX_AGE = 150; // 常量,命名规范:全大写+下划线
MAX_AGE = 200; // 编译错误:不能重新赋值

五、核心执行顺序(重点!)

当创建对象或加载类时,代码执行顺序是:
静态内容(静态属性 / 静态代码块)→ 普通内容(普通属性 / 普通代码块)→ 构造方法

详细规则:
  1. 静态内容:类加载时执行,按代码定义顺序执行,只执行一次。
  2. 普通内容:每次创建对象时执行,按代码定义顺序执行(普通属性和普通代码块谁在前先执行谁)。
  3. 构造方法:每次创建对象时,在普通内容之后执行。
结合Dog类分析执行顺序:
public class Dog {
    // 静态属性(属于静态内容)
    public static Dog aa = new Dog(); 
    
    // 普通属性1
    public int a = 10;
    
    // 普通代码块1(普通内容)
    { System.out.println("代码块1:"+a); }
    
    // 普通属性2
    public int b = 20;
    
    // 普通代码块2(普通内容)
    { 
        System.out.println("代码块2:"+b); 
        System.out.println("代码块2:"+a); 
    }
    
    // 构造方法
    public Dog() {
        System.out.println(a);
        System.out.println(b);
    }
}

执行过程(关键!):

  1. Dog类被加载时,先执行静态属性aa = new Dog()(触发创建Dog对象)。
  2. 创建对象时,先执行普通内容(按顺序):
    • 初始化a = 10
    • 执行代码块 1:输出代码块1:10
    • 初始化b = 20
    • 执行代码块 2:输出代码块2:20代码块2:10
  3. 执行构造方法:输出1020
  4. 静态属性aa初始化完成(此时Dog类加载的静态内容执行完毕)。

六、继承中的执行顺序

如果有父类和子类,执行顺序会更复杂,规则是:
父类静态内容 → 子类静态内容 → 父类普通内容 → 父类构造方法 → 子类普通内容 → 子类构造方法

class Animal { // 父类
    static { System.out.println("父类静态代码块"); }
    { System.out.println("父类普通代码块"); }
    public Animal() { System.out.println("父类构造方法"); }
}

class Dog extends Animal { // 子类
    static { System.out.println("子类静态代码块"); }
    { System.out.println("子类普通代码块"); }
    public Dog() { System.out.println("子类构造方法"); }
}

// 执行:new Dog(); 
// 输出顺序:
// 父类静态代码块
// 子类静态代码块
// 父类普通代码块
// 父类构造方法
// 子类普通代码块
// 子类构造方法

示例:

总结

面向对象编程是 Java 开发的核心思想,掌握类与对象的概念、四大特征(封装、继承、多态、接口)以及核心关键字的用法,是构建高质量 Java 程序的基础。通过抽象现实世界、封装细节、利用继承实现复用、借助多态提升扩展性,能让你的代码更贴近现实逻辑、更易于维护和扩展。建议结合实际案例多做练习,尤其是多态和接口的应用,这是 Java 编程能力进阶的关键。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐