Java 面向对象编程,英文叫 Object-Oriented Programming,OOP

它的核心思想是:

把现实世界中的事物抽象成“对象”,对象有自己的属性和行为。

比如现实中有一个学生:

学生:
属性:姓名、年龄、成绩
行为:学习、考试、自我介绍

放到 Java 里,就可以写成一个类。


1. 什么是类和对象?

类:一种模板

类可以理解成“图纸”或者“模板”。

比如定义一个学生类:

class Student {
    String name;
    int age;
    double score;

    public void study() {
        System.out.println(name + " 正在学习");
    }

    public void introduce() {
        System.out.println("我叫 " + name + ",今年 " + age + " 岁");
    }
}

这里的 Student 就是一个类。

它描述了学生有什么:

String name;
int age;
double score;

也描述了学生能做什么:

study()
introduce()

对象:根据类创建出来的具体东西

有了类之后,就可以创建对象:

public class Main {
    public static void main(String[] args) {
        Student s1 = new Student();

        s1.name = "张三";
        s1.age = 18;
        s1.score = 90.5;

        s1.study();
        s1.introduce();
    }
}

输出:

张三 正在学习
我叫 张三,今年 18 岁

这里:

Student s1 = new Student();

表示创建了一个 Student 对象。

可以理解为:

Student 是学生模板
s1 是一个具体学生

2. 类和对象的关系

类和对象的关系可以这样理解:

类:手机设计图
对象:根据设计图生产出来的具体手机

类:学生模板
对象:张三、李四、王五

类:汽车模板
对象:奔驰、宝马、比亚迪

例如:

Student s1 = new Student();
Student s2 = new Student();

s1.name = "张三";
s2.name = "李四";

s1s2 都是学生对象,但它们的数据不同。


3. 成员变量和成员方法

在类里面定义的变量,叫成员变量

class Student {
    String name;
    int age;
}

在类里面定义的方法,叫成员方法

class Student {
    public void study() {
        System.out.println("正在学习");
    }
}

完整例子:

class Student {
    String name;
    int age;

    public void study() {
        System.out.println(name + " 正在学习");
    }
}

使用:

public class Main {
    public static void main(String[] args) {
        Student stu = new Student();

        stu.name = "小明";
        stu.age = 20;

        stu.study();
    }
}

输出:

小明 正在学习

4. 构造方法

构造方法用于在创建对象时初始化数据。

不用构造方法时,你可能这样写:

Student s = new Student();
s.name = "张三";
s.age = 18;

如果使用构造方法,可以这样写:

Student s = new Student("张三", 18);

定义方式如下:

class Student {
    String name;
    int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void introduce() {
        System.out.println("我叫 " + name + ",今年 " + age + " 岁");
    }
}

使用:

public class Main {
    public static void main(String[] args) {
        Student s1 = new Student("张三", 18);
        Student s2 = new Student("李四", 20);

        s1.introduce();
        s2.introduce();
    }
}

输出:

我叫 张三,今年 18 岁
我叫 李四,今年 20 岁

注意:构造方法的名字必须和类名一样。

public Student(String name, int age)

这里 Student 就是构造方法名。


5. this 关键字

this 表示当前对象。

比如:

class Student {
    String name;
    int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

这里有两个 name

this.name = name;

左边的:

this.name

表示对象自己的成员变量。

右边的:

name

表示构造方法传进来的参数。

可以理解为:

把传进来的 name,赋值给当前对象自己的 name。

6. 面向对象的三大特征

Java 面向对象有三个重要特征:

封装
继承
多态

这是 Java 学习中非常核心的内容。


7. 封装

封装就是:

把对象内部的数据保护起来,不让外部随便修改,只通过指定方法访问。

比如不推荐这样写:

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

因为外部可以乱改:

Student s = new Student();
s.age = -100;

年龄变成 -100,明显不合理。

更好的写法是:

class Student {
    private String name;
    private int age;

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

    public int getAge() {
        return age;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

使用:

public class Main {
    public static void main(String[] args) {
        Student s = new Student();

        s.setName("张三");
        s.setAge(18);

        System.out.println(s.getName());
        System.out.println(s.getAge());

        s.setAge(-100);
    }
}

输出:

张三
18
年龄不合法

这就是封装。

封装的常见写法是:

成员变量 private
对外方法 public

8. 继承

继承就是:

子类可以继承父类的属性和方法。

比如猫和狗都是动物。

先定义一个父类:

class Animal {
    String name;

    public void eat() {
        System.out.println(name + " 正在吃东西");
    }
}

定义狗类继承动物类:

class Dog extends Animal {
    public void bark() {
        System.out.println(name + " 正在汪汪叫");
    }
}

使用:

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog();

        dog.name = "小黑";
        dog.eat();
        dog.bark();
    }
}

输出:

小黑 正在吃东西
小黑 正在汪汪叫

这里:

class Dog extends Animal

表示 Dog 继承了 Animal

所以 Dog 可以使用 Animal 里的:

String name;
public void eat()

9. 为什么要用继承?

假设不用继承,你可能会这样写:

class Dog {
    String name;

    public void eat() {
        System.out.println(name + " 正在吃东西");
    }

    public void bark() {
        System.out.println(name + " 正在汪汪叫");
    }
}

class Cat {
    String name;

    public void eat() {
        System.out.println(name + " 正在吃东西");
    }

    public void catchMouse() {
        System.out.println(name + " 正在抓老鼠");
    }
}

你会发现 DogCat 都有:

String name;
public void eat()

重复了。

可以把公共部分抽出来:

class Animal {
    String name;

    public void eat() {
        System.out.println(name + " 正在吃东西");
    }
}

然后:

class Dog extends Animal {
    public void bark() {
        System.out.println(name + " 正在汪汪叫");
    }
}

class Cat extends Animal {
    public void catchMouse() {
        System.out.println(name + " 正在抓老鼠");
    }
}

这样代码更简洁。


10. 方法重写 Override

子类可以重写父类的方法。

比如父类:

class Animal {
    public void makeSound() {
        System.out.println("动物发出声音");
    }
}

子类:

class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("狗汪汪叫");
    }
}

测试:

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.makeSound();
    }
}

输出:

狗汪汪叫

这里 Dog 重写了 AnimalmakeSound() 方法。

@Override 表示这是一个重写方法。虽然不写也可以,但建议写上,便于检查错误。


11. 多态

多态是面向对象里比较重要、也稍微抽象的概念。

简单说:

同一个父类引用,指向不同子类对象,调用同一个方法,会表现出不同结果。

例如:

class Animal {
    public void makeSound() {
        System.out.println("动物发出声音");
    }
}

class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("狗汪汪叫");
    }
}

class Cat extends Animal {
    @Override
    public void makeSound() {
        System.out.println("猫喵喵叫");
    }
}

使用:

public class Main {
    public static void main(String[] args) {
        Animal a1 = new Dog();
        Animal a2 = new Cat();

        a1.makeSound();
        a2.makeSound();
    }
}

输出:

狗汪汪叫
猫喵喵叫

虽然变量类型都是 Animal

Animal a1
Animal a2

但是实际对象不同:

new Dog()
new Cat()

所以调用 makeSound() 时,结果不同。

这就是多态。


12. 多态有什么用?

比如你写一个方法:

public static void letAnimalSpeak(Animal animal) {
    animal.makeSound();
}

它可以接收所有动物:

public class Main {
    public static void letAnimalSpeak(Animal animal) {
        animal.makeSound();
    }

    public static void main(String[] args) {
        Dog dog = new Dog();
        Cat cat = new Cat();

        letAnimalSpeak(dog);
        letAnimalSpeak(cat);
    }
}

输出:

狗汪汪叫
猫喵喵叫

好处是:你不用分别写:

letDogSpeak(Dog dog)
letCatSpeak(Cat cat)

只需要写一个:

letAnimalSpeak(Animal animal)

以后再加一个 Bird 类,也能直接用。

class Bird extends Animal {
    @Override
    public void makeSound() {
        System.out.println("鸟叽叽叫");
    }
}

然后:

Bird bird = new Bird();
letAnimalSpeak(bird);

这就是多态的价值:提高代码扩展性


13. 抽象类

有时候父类只是一个抽象概念,不应该直接创建对象。

比如 Animal 是动物的抽象概念,真正存在的是狗、猫、鸟。

可以写成抽象类:

abstract class Animal {
    String name;

    public abstract void makeSound();

    public void eat() {
        System.out.println(name + " 正在吃东西");
    }
}

注意:

public abstract void makeSound();

这是抽象方法,只有方法声明,没有方法体。

子类必须实现它:

class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("狗汪汪叫");
    }
}

抽象类不能直接创建对象:

Animal a = new Animal(); // 错误

只能创建子类对象:

Animal a = new Dog();

14. 接口

接口可以理解成一种“规范”或“能力”。

比如会飞是一种能力:

interface Flyable {
    void fly();
}

鸟会飞:

class Bird implements Flyable {
    @Override
    public void fly() {
        System.out.println("鸟在飞");
    }
}

飞机也会飞:

class Plane implements Flyable {
    @Override
    public void fly() {
        System.out.println("飞机在飞");
    }
}

使用:

public class Main {
    public static void main(String[] args) {
        Flyable f1 = new Bird();
        Flyable f2 = new Plane();

        f1.fly();
        f2.fly();
    }
}

输出:

鸟在飞
飞机在飞

15. 抽象类和接口的简单区别

初学阶段可以这样理解:

概念 更像什么 例子
抽象类 一类事物的共同父类 动物、交通工具
接口 一种能力或规范 会飞、会游泳、可充电

例如:

abstract class Animal {
    public abstract void eat();
}

表示“动物”这一类东西。

interface Flyable {
    void fly();
}

表示“会飞”这个能力。

一个类只能继承一个父类:

class Dog extends Animal

但可以实现多个接口:

class Duck extends Animal implements Flyable, Swimmable

16. 一个完整例子:动物系统

下面这个例子把封装、继承、多态放在一起。

abstract class Animal {
    private String name;

    public Animal(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public abstract void makeSound();

    public void eat() {
        System.out.println(name + " 正在吃东西");
    }
}

class Dog extends Animal {
    public Dog(String name) {
        super(name);
    }

    @Override
    public void makeSound() {
        System.out.println(getName() + ":汪汪!");
    }
}

class Cat extends Animal {
    public Cat(String name) {
        super(name);
    }

    @Override
    public void makeSound() {
        System.out.println(getName() + ":喵喵!");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal a1 = new Dog("小黑");
        Animal a2 = new Cat("小花");

        a1.eat();
        a1.makeSound();

        a2.eat();
        a2.makeSound();
    }
}

输出:

小黑 正在吃东西
小黑:汪汪!
小花 正在吃东西
小花:喵喵!

这里体现了:

封装:name 是 private,通过 getName() 访问
继承:Dog 和 Cat 继承 Animal
多态:Animal a1 = new Dog(); Animal a2 = new Cat();
抽象:Animal 中的 makeSound() 让子类自己实现

17. 面向对象的核心思维

初学 Java 时,你可以这样思考一个程序:

第一步:找对象

比如做一个学生管理系统,有哪些对象?

学生
老师
课程
成绩
班级

第二步:找属性

学生有什么属性?

姓名
年龄
学号
成绩

第三步:找行为

学生能做什么?

学习
考试
查看成绩

第四步:写成类

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

    public Student(String name, int age, String studentId) {
        this.name = name;
        this.age = age;
        this.studentId = studentId;
    }

    public void displayInfo() {
        System.out.println("Name: " + name + ", Age: " + age + ", ID: " + studentId);
    }
}
class GraduateStudent extends Student {
    private String researchField;

    public GraduateStudent(String name, int age, String studentId, String researchField) {
        super(name, age, studentId);
        this.researchField = researchField;
    }

    @Override
    public void displayInfo() {
        super.displayInfo();
        System.out.println("Research Field: " + researchField);
    }
}
public class StudentManagement {
    public static void main(String[] args) {
        Student s1 = new Student("Alice", 20, "S12345");
        GraduateStudent g1 = new GraduateStudent("Bob", 25, "G54321", "AI Research");

        s1.displayInfo();
        g1.displayInfo();
    }
}

输出:

Name: Alice, Age: 20, ID: S12345
Name: Bob, Age: 25, ID: G54321
Research Field: AI Research

这就是面向对象的基本建模方式。

更多推荐