源本科技 | 码上会

Java 接口入门

2025/12/27
60
0

学习目标

  • 理解 Java 接口的基本概念及其在面向对象编程中的作用

  • 掌握接口的定义、实现方式及与类的关系

  • 了解 Java 8 和 Java 9 为接口引入的新特性(默认方法、静态方法、私有方法等)

  • 能够在实际开发中合理使用接口实现多继承和行为契约


什么是 Java 接口

接口(Interface) 是 Java 中一种特殊的抽象类型,用于定义一组必须被实现的方法。它本质上是一个行为契约:规定了“做什么”,但不规定“怎么做”。

核心特点

  • 接口中的所有变量默认是 public static final(即常量)

  • 接口中的方法在 Java 8 之前只能是 public abstract(无方法体)

  • Java 8 起,接口可包含:

    • default 方法(带默认实现)

    • static 方法(通过接口名调用)

  • Java 9 起,接口还可包含 private 方法(仅用于内部辅助)

用途:实现抽象多重继承(Java 类不支持多继承,但可实现多个接口)


接口基础示例

// 定义接口
interface TestInterface {
    // 默认为 public static final
    int a = 10;

    // 默认为 public abstract
    void display();
}

// 实现接口的类
class TestClass implements TestInterface {
    @Override
    public void display() {
        System.out.println("Coder");
    }
}

class Main {
    public static void main(String[] args) {
        TestClass t = new TestClass();
        t.display();      // 输出: Coder
        System.out.println(t.a); // 输出: 10
    }
}
Coder
10

注意

  • 实现接口必须使用 implements 关键字

  • 必须实现接口中所有抽象方法(除非该类是抽象类)


何时使用类 vs 接口

场景

使用类(Class)

使用接口(Interface)

表示具有状态和行为的实体

✅ 如 Student, Car

定义通用行为契约

✅ 如 Comparable, Runnable

需要保存实例变量(状态)

❌(接口只有常量)

实现多继承效果

❌(Java 不支持类的多继承)

✅(一个类可实现多个接口)

实际案例:交通工具接口

interface Vehicle {
    void changeGear(int gear);
    void speedUp(int increment);
    void applyBrakes(int decrement);
}

class Bicycle implements Vehicle {
    int speed, gear;
    
    @Override public void changeGear(int g) { gear = g; }
    @Override public void speedUp(int i) { speed += i; }
    @Override public void applyBrakes(int d) { speed -= d; }
    
    void printStates() {
        System.out.println("speed: " + speed + " gear: " + gear);
    }
}

class ElectricBike implements Vehicle {
    int speed, gear;
    
    @Override public void changeGear(int g) { gear = g; }
    @Override public void speedUp(int i) { speed += i * 2; } // 电助力加速更快
    @Override public void applyBrakes(int d) { speed = Math.max(0, speed - d); }
    
    void printStates() {
        System.out.println("ElectricBike - speed: " + speed + " gear: " + gear);
    }
}

class Main {
    public static void main(String[] args) {
        Bicycle bike = new Bicycle();
        bike.changeGear(2);
        bike.speedUp(3);
        bike.applyBrakes(1);
        System.out.print("Bicycle state: ");
        bike.printStates();

        ElectricBike eBike = new ElectricBike();
        eBike.changeGear(1);
        eBike.speedUp(2);
        eBike.applyBrakes(1);
        System.out.print("ElectricBike state: ");
        eBike.printStates();
    }
}
Bicycle state: speed: 2 gear: 2
ElectricBike state: speed: 3 gear: 1

优势:不同类以各自方式实现相同接口,保证行为一致性,提升代码可扩展性。


接口实现多重继承

Java 类不能继承多个类,但可以实现多个接口:

interface Adder {
    int add(int a, int b);
}

interface Subtractor {
    int subtract(int a, int b);
}

class Calculator implements Adder, Subtractor {
    @Override
    public int add(int a, int b) {
        return a + b;
    }

    @Override
    public int subtract(int a, int b) {
        return a - b;
    }
}

class Main {
    public static void main(String[] args) {
        Calculator calc = new Calculator();
        System.out.println("Add: " + calc.add(5, 3));       // 8
        System.out.println("Subtract: " + calc.subtract(5, 3)); // 2
    }
}
Add: 8
Subtract: 2

Java 8+ 接口新特性

1. 默认方法

允许在接口中提供方法的默认实现,避免破坏已有实现类。

interface Drawable {
    default void draw() {
        System.out.println("Drawing a shape.");
    }
}

class Circle implements Drawable {
    // 可选择重写,也可直接使用默认实现
}

class Main {
    public static void main(String[] args) {
        new Circle().draw(); // 输出: Drawing a shape.
    }
}

2. 静态方法

通过接口名直接调用,不被实现类继承。

interface MathUtils {
    static int multiply(int a, int b) {
        return a * b;
    }
}

class Main {
    public static void main(String[] args) {
        System.out.println(MathUtils.multiply(4, 5)); // 20
    }
}

3. 函数式接口

仅含一个抽象方法的接口,可用 Lambda 表达式简化实现。

@FunctionalInterface
interface Operation {
    int execute(int x, int y);
}

class Main {
    public static void main(String[] args) {
        Operation add = (a, b) -> a + b;
        System.out.println(add.execute(10, 20)); // 30
    }
}

@FunctionalInterface 注解非必需,但建议使用以增强可读性和编译检查。


Java 9+ 接口中的私有方法

用于封装接口内部的公共逻辑,避免代码重复。

interface Vehicle {
    private void log(String msg) {
        System.out.println("[LOG] " + msg);
    }

    default void start() {
        log("Engine starting...");
        log("Engine started!");
    }
}

class Car implements Vehicle {}

class Main {
    public static void main(String[] args) {
        new Car().start();
    }
}
[LOG] Engine starting...
[LOG] Engine started!

注意:私有方法不能被实现类访问或重写,仅限接口内部使用。


接口的继承

接口可通过 extends 继承其他接口:

interface A {
    void methodA();
}

interface B extends A {
    void methodB();
}

class MyClass implements B {
    public void methodA() { System.out.println("A"); }
    public void methodB() { System.out.println("B"); }
}

class Main {
    public static void main(String[] args) {
        MyClass obj = new MyClass();
        obj.methodA(); // A
        obj.methodB(); // B
    }
}

实现类必须提供继承链中所有抽象方法的实现。


类与接口的区别

特性

类(Class)

接口(Interface)

实例化

可创建对象

不能直接实例化

变量

可有实例变量

public static final 常量

方法

可有具体方法

默认抽象 Java 8+ 支持 default/static

继承

单继承(extends

多继承 extends 多个接口

构造器

支持

不支持

访问修饰符

private/protected/public/default

所有成员默认 public

关键字

class

interface

main 方法

可有

Java 8+ 可通过 static 方法实现


重点总结

  • 接口是行为契约,强调“能做什么”而非“如何做”

  • 实现接口必须用 implements,并实现所有抽象方法

  • Java 8 引入 defaultstatic 方法,增强接口灵活性

  • Java 9 新增 private 方法,支持接口内部逻辑复用

  • 接口支持多重继承,是 Java 实现多继承的唯一合法途径

  • 合理使用接口可提升代码的解耦性、可测试性与可扩展性


思考题

  1. 为什么 Java 不允许类实现多继承,却允许接口多继承?这解决了什么问题?

  2. 如果一个类同时继承一个父类并实现一个接口,而两者都有同名方法,会发生什么?如何解决?

  3. 在什么场景下你会优先选择抽象类而不是接口?反之亦然?