子父类是包含关系,接口用于关系网。

接口与实现

相关主线:面对对象的程序与设计(基础入门)抽象类多态

接口(Interface)

  • 在Java中,接口是一种引用类型,用于定义一组抽象方法(Java 8+ 支持默认方法、静态方法、私有方法)。
  • 使用关键字 interface 声明。
  • 所有方法默认是 public abstract,字段(变量)默认是 public static final(因此是常量),因此继承重写时方法需 public
  • 接口中变量默认public,static,final
  • 抽象方法不能被 staticfinal 修饰。
  • 接口没有构造函数

default 方法(接口默认方法)

  • 是什么:Java 8 引入,用 default 关键字声明,方法体必须存在。
  • 为什么:在不破坏已有实现类的前提下,向接口添加新方法
  • 怎么用
    • 实现类可继承默认实现,也可重写。
    • 重写时可选调用原接口的默认方法:接口名.super.方法()
  • 冲突:一个类实现多个接口,若多个接口有同名 default 方法,则必须在类中重写,否则编译报错。
  • 注意:default 方法不能访问实例字段(接口无实例字段),且与 Object 类的方法(如 toString)冲突时,实现接口的子类优先采用 Object 的。

定义接口

public interface Flyable {
    void fly(); // 抽象方法
    default void glide() { // 默认方法
        System.out.println("滑翔中...");
    }
    static void info() { // 静态方法
        System.out.println("Flyable 接口");
    }
}

实现接口(Implements)

  • 类通过 implements 关键字实现一个或多个接口。
  • 必须实现接口中所有的抽象方法(除非类是抽象类)。
  • 必须实现final常量
  • default也继承,可理解为有默认方法体的abstract void
  • 重写时不可省略public(不能降低访问权限)
  • 类继承接口时继承除static、private的方法
  • 不能继承接口常量,只是能够调用接口常量

抽象类实现接口

抽象类实现接口时,可以只实现部分抽象方法,未实现的自动成为该抽象类的抽象方法,继续传递给子类。同时,抽象类可以:

  • 直接继承接口的 default 方法(无需实现)。
  • 无法继承接口的 static 方法(只能通过接口名调用)。
  • 重写 default 方法,也可在其中调用 接口名.super.方法()

这种机制使抽象类在接口与具体类之间充当部分实现者,适合定义通用行为、保留可变部分由子类定制。

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

接口回调(Interface Callback)

  • 定义:将实现了某个接口的对象引用传递给另一个方法,由该方法在适当时候回调该接口中定义的方法。
  • 本质:一种解耦的设计模式——调用方只依赖接口,不关心具体实现类。
  • 典型场景:按钮点击事件、异步任务完成后通知。
  • 示例
    interface Callback {
        void onComplete(String result);
    }
     
    class Task {
        void execute(Callback cb) {
            // 执行任务...
            cb.onComplete("完成"); // 回调
        }
    }
     
    class Main implements Callback {
        public void onComplete(String result) {
            System.out.println(result);
        }
        public static void main(String[] args) {
            new Task().execute(new Main()); // 传入回调对象
        }
    }
  • 特点:实现类不知道回调何时被触发,只负责实现接口方法;触发时机由调用方决定。

函数式接口与 Lambda 表达式

函数式接口(Functional Interface)

  • 定义:只包含一个抽象方法的接口(可以有 default、static 方法)。
  • 注解@FunctionalInterface(可选,加上的话编译器会检查是否符合函数式接口规范)。
  • 常见内置函数式接口
接口方法用途
Runnablevoid run()无参无返回值
Supplier<T>T get()提供者,无参有返回值
Consumer<T>void accept(T t)消费者,有参无返回值
Function<T,R>R apply(T t)类型转换,有参有返回值
Predicate<T>boolean test(T t)判断,有参返回 boolea n

Lambda 表达式

面向只有一个抽象方法的接口(只需要重写一个抽象方法),用于简化代码 匿名类 上下文推断输入类型

  • 本质:函数式接口的简洁写法,替代匿名内部类,指代对应接口或父类的子类。
  • 语法(参数列表) -> { 方法体 }
    • 参数类型可省略(编译器推断)。
    • 单参数可省略括号(如 x -> x * 2)。
    • 单行方法体可省略花括号和 return
  • 示例
// 匿名内部类写法
Runnable r1(变量名被赋予引用地址) = new Runnable() {
    @Override
    public void run() {
        System.out.println("run");
    }
};
 
// Lambda 写法
Runnable r2 = () -> System.out.println("run");
// 比较器
Comparator<String> comp = (s1, s2) -> s1.length() - s2.length();

方法引用(Method Reference)

  • Lambda 的进一步简化,当 Lambda 体只是调用一个现有方法时使用
  • 格式:类名::方法名对象::方法名
类型示例等价 Lambda
静态方法Integer::parseInts -> Integer.parseInt(s)
实例方法(特定对象)System.out::printlnx -> System.out.println(x)
实例方法(任意对象)String::lengths -> s.length()
构造器ArrayList::new() -> new ArrayList<>()

注意

  • Lambda 表达式只能用于函数式接口
  • Lambda 中引用的局部变量必须是 final 或 effectively final(不可被后续修改)。

接口的特性

  • 多继承:一个类可以实现多个接口,弥补单继承的不足。(关系网)
  • 接口可以继承接口:使用 extends 关键字,支持多继承。
  • 默认方法:提供默认实现,子类可以重写或直接使用。
  • 静态方法:不能被子类继承或重写,只能通过接口名调用。
  • 私有方法(Java 9+):用于在接口内部复用代码,不对外暴露。

接口 vs 抽象类

特性接口抽象类
关键字interfaceabstract class
构造器
多继承支持(类可以实现多个接口)不支持(单继承)
字段只能是 public static final可以有实例变量
方法抽象方法、默认、静态、私有抽象方法、具体方法

使用场景

  • 定义行为规范(如可飞行、可比较 Comparable)。
  • 实现松耦合设计(面向接口编程)。
  • 利用默认方法在不破坏现有实现的前提下扩展接口功能。

参考:多态抽象类、面向对象设计原则


面对对象的程序与设计(基础入门) 子类与继承 抽象类 多态 接口回调与上转型运用