ToolkitX
知识库工具箱

面向对象

封装、继承、多态、抽象类与接口

30min·进阶

01. 面向对象三大特性

Java 是纯面向对象的语言,万物皆对象。三大特性封装、继承、多态是面试必问。封装就是把数据和方法包在一起,对外只暴露必要的接口,隐藏实现细节。继承就是子类复用父类的代码,用 extends 关键字。多态就是同一个方法名不同对象表现出不同行为。
java
// 封装
public class BankAccount {
    private double balance;
    public double getBalance() { return balance; }
    public void deposit(double amount) { balance += amount; }
}

// 继承
public class SavingsAccount extends BankAccount {
    private double interestRate;
}

02. 抽象类和接口的区别

抽象类用 abstract 修饰,可以有普通方法和抽象方法,单继承。接口用 interface 定义,JDK8 之后可以有默认方法和静态方法,多实现。什么时候用哪个?类之间有 is-a 关系用抽象类,定义行为规范用接口。接口是做什么的契约,抽象类是是什么的模板。
java
public abstract class Animal {
    public abstract void makeSound();
    public void sleep() { System.out.println("Zzz"); }
}

public interface Flyable {
    void fly();
    default void land() { System.out.println("landing..."); }
}

public class Bird extends Animal implements Flyable {
    // 必须实现两个抽象方法
}
优先使用接口而不是抽象类,因为接口更灵活,支持多实现。

03. 构造函数和重载

构造函数用来初始化对象,名字和类名一模一样,没有返回值。一个类可以有多个构造函数,参数列表不同,这叫重载。构造函数之间可以用 this() 互相调用,但必须写在第一行。默认构造函数是不带参数的,一旦你自己写了构造函数,默认的就没有了。
java
public class Student {
    private String name;
    private int age;

    public Student() { this("无名", 18); }
    public Student(String name) { this(name, 18); }
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
一旦你定义了带参数的构造函数,无参构造函数就消失了,需要显式声明。

04. static 和 final 关键字

static 表示属于类而不是属于某个对象的。static 变量所有对象共享一份,static 方法不用 new 对象就能调用。final 表示不可变:修饰变量不能改值,修饰方法不能被子类重写,修饰类不能被子类继承。public static final 就是常量的标准写法。
java
public class MathUtils {
    public static final double PI = 3.14159;

    public static int add(int a, int b) {
        return a + b;
    }
}

// 直接调用
int result = MathUtils.add(3, 5);
System.out.println(MathUtils.PI);

05. 内部类和匿名内部类

内部类是定义在一个类里面的类,可以访问外部类的私有成员。匿名内部类没有名字,直接 new 接口或抽象类当场实现方法。在 Lambda 表达式出来之前,匿名内部类用得很多,比如事件监听器。现在能换成 Lambda 的场景尽量用 Lambda,代码更简洁。
java
// 匿名内部类
button.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("点击了");
    }
});

// Lambda 替代(更简洁)
button.addActionListener(e -> System.out.println("点击了"));
能用 Lambda 替换匿名内部类的地方尽量替换,代码可读性大幅提升。

知识测验

1/4正确 0

Java 中 extends 关键字表示什么关系?

下一节

集合框架

下一节