杰瑞科技汇

Java中implements的关键作用是什么?

实现接口

implements 是 Java 中的一个关键字,用于让一个实现一个或多个接口

Java中implements的关键作用是什么?-图1
(图片来源网络,侵删)

你可以把它理解为“签订合同”或“扮演某个角色”,接口定义了一组规范(方法签名),而 implements 关键字的作用就是告诉编译器:“这个类承诺会遵守接口中定义的所有规范”。


为什么需要 implements?(接口的作用)

在深入 implements 之前,我们先理解接口的三大核心作用:

  1. 实现多继承:Java 不支持一个类直接继承多个类(为了避免“菱形问题”带来的复杂性),但一个类可以实现多个接口,这弥补了单继承的不足。
  2. 定义规范/契约:接口定义了一组方法,但没有具体的实现,它规定了“能做什么”,但不管“怎么做”,这就像一份蓝图,告诉所有实现者必须有哪些功能。
  3. 实现解耦:通过面向接口编程,我们可以降低代码之间的耦合度,调用方只关心接口,而不关心具体的实现类,这使得系统更灵活、更容易扩展和测试。

implements 的基本语法

语法非常简单:

public class MyClass implements Interface1, Interface2 {
    // 类的实现代码
}
  • MyClass:你想要实现接口的那个类。
  • implements:关键字。
  • Interface1, Interface2:一个或多个要实现的接口,多个接口之间用逗号 分隔。

implements 的核心规则

当一个类使用 implements 关键字后,它必须遵守以下规则:

Java中implements的关键作用是什么?-图2
(图片来源网络,侵删)

必须实现所有方法

类必须提供接口中所有方法的“具体实现”(方法体),如果接口中的方法是 public abstract 的(这是接口方法的默认修饰符),那么实现类就必须将这些方法声明为 public 并提供实现代码。

示例:

// 1. 定义一个接口
interface Flyable {
    // 接口中的方法默认是 public abstract 的
    void fly();
}
// 2. 定义一个类,并实现这个接口
class Bird implements Flyable {
    // 3. 必须实现接口中的 fly() 方法
    @Override
    public void fly() {
        System.out.println("Bird is flying by flapping its wings.");
    }
}
// 3. 另一个实现类
class Airplane implements Flyable {
    @Override
    public void fly() {
        System.out.println("Airplane is flying using jet engines.");
    }
}

访问修饰符必须兼容

接口方法的默认修饰符是 public,实现类中的方法访问权限必须大于或等于 public,由于 public 是最宽松的,所以实现类中的方法必须声明为 public

interface Runnable {
    void run(); // 默认是 public abstract void run();
}
class Athlete implements Runnable {
    // 错误!不能将访问权限从 public 降低为 protected
    // protected void run() { ... } // 编译错误
    // 正确!必须使用 public
    @Override
    public void run() {
        System.out.println("Athlete is running fast.");
    }
}

可以重写接口方法

实现类不仅可以提供接口方法的实现,还可以像重写父类方法一样重写接口方法,以提供更具体或不同的行为。

Java中implements的关键作用是什么?-图3
(图片来源网络,侵删)
interface Animal {
    void makeSound();
}
class Dog implements Animal {
    @Override
    public void makeSound() {
        System.out.println("Woof! Woof!");
    }
}
class Cat implements Animal {
    @Override
    public void makeSound() {
        System.out.println("Meow.");
    }
}

处理默认方法(Default Methods)

从 Java 8 开始,接口中可以包含默认方法(使用 default 关键字修饰),默认方法有方法体,即有默认实现。

规则:默认方法不是必须实现的

如果一个类实现了一个包含默认方法的接口,它可以选择不实现这个默认方法,直接“继承”并使用接口提供的默认实现,它也可以选择重写这个默认方法。

示例:

interface Vehicle {
    void start();
    // 默认方法
    default void honk() {
        System.out.println("Beep beep!");
    }
}
class Car implements Vehicle {
    @Override
    public void start() {
        System.out.println("Car started with a key.");
    }
    // Car 选择不重写 honk(),直接使用接口的默认实现
}
class Motorcycle implements Vehicle {
    @Override
    public void start() {
        System.out.println("Motorcycle started with a button.");
    }
    // Motorcycle 重写了 honk() 方法
    @Override
    public void honk() {
        System.out.println("Honk! Honk! Loud and clear!");
    }
}

处理静态方法(Static Methods)

从 Java 8 开始,接口还可以包含静态方法(使用 static 关键字修饰)。

规则:静态方法不能被实现

接口的静态方法属于接口本身,而不是实现类,实现类不能也不需要实现或重写接口的静态方法,你只能通过接口名来调用它们。

interface MathUtils {
    // 静态方法
    static int add(int a, int b) {
        return a + b;
    }
}
class Calculator implements MathUtils {
    // 不能也不能重写 add() 方法
    // @Override
    // static int add(int a, int b) { ... } // 编译错误
}
public class Main {
    public static void main(String[] args) {
        // 通过接口名调用静态方法
        int sum = MathUtils.add(10, 20);
        System.out.println("Sum: " + sum); // 输出: Sum: 30
    }
}

implements vs extends

这是一个非常常见且重要的区别。

特性 extends (继承) implements (实现)
关系 "是一个" (is-a) 的关系。 "能做" (can-do) 的关系。
作用对象 类与类之间,类与抽象类之间。 类与接口之间。
目的 代码复用建立父子层级关系,子类继承父类的状态(字段)和行为(方法)。 定义规范实现多态,实现类承诺遵循接口的契约。
方法 可以重写(@Override)非 privatefinal 的方法。 必须实现所有抽象方法,可以重写默认方法。
字段 可以继承父类的非 private 字段。 不能继承接口中的字段(接口中的字段默认是 public static final 的,属于接口本身,不是实例变量)。

简单记忆:

  • extends 是为了“继承”已有的代码和结构,建立“父子”关系。
  • implements 是为了“遵守”一个“合同”,获得某种“能力”或“身份”。

一个类可以同时使用 extendsimplements

// 一个类可以继承一个父类,同时实现多个接口
class MyClass extends MySuperClass implements Interface1, Interface2 {
    // ...
}

实际应用场景

implements 是 Java 面向对象编程的基石之一,无处不在。

回调机制

// 定义一个监听器接口
interface ButtonClickListener {
    void onClick();
}
// UI 按钮类
class Button {
    private ButtonClickListener listener;
    public void setListener(ButtonClickListener listener) {
        this.listener = listener;
    }
    public void click() {
        System.out.println("Button was clicked.");
        if (listener != null) {
            listener.onClick(); // 回调接口方法
        }
    }
}
// 具体的点击行为实现
class SaveAction implements ButtonClickListener {
    @Override
    public void onClick() {
        System.out.println("Saving the document...");
    }
}
public class App {
    public static void main(String[] args) {
        Button saveButton = new Button();
        saveButton.setListener(new SaveAction()); // 注入实现
        saveButton.click(); // 输出: Button was clicked. Saving the document...
    }
}

框架和库的设计

Spring、Hibernate 等框架大量使用接口。Runnable 接口是 Java 并发的基础。

// 实现 Runnable 接口来创建一个线程
class MyTask implements Runnable {
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println("Task running: " + i);
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
public class Main {
    public static void main(String[] args) {
        Thread thread = new Thread(new MyTask());
        thread.start();
    }
}
  • implements 用于让一个类实现一个或多个接口。
  • 它的核心作用是定义规范实现多态
  • 实现类必须提供接口中所有抽象方法的具体实现。
  • 接口中的默认方法可以被实现类直接使用或重写。
  • 接口中的静态方法不能被实现类重写,只能通过接口名调用。
  • implementsextends 的主要区别在于:extends 用于继承和代码复用,而 implements 用于遵守契约和获得能力。
分享:
扫描分享到社交APP
上一篇
下一篇