函数式接口不能被类继承,但可extends其他接口且必须保持仅一个抽象方法;核心是@functionalinterface标注、单一抽象方法约束及default方法安全增强。

Java 中函数式接口不参与传统意义上的“继承体系”,它本身不是用来被继承的,而是被实现的;设计重点在于语义清晰、职责单一、可组合,且必须严格满足“仅含一个抽象方法”的约束。
函数式接口不能被继承,但可以扩展其他接口
函数式接口用 @FunctionalInterface 标注,核心要求是:接口中**只有一个抽象方法**(默认方法、静态方法、重载的 Object 方法不计)。它不支持被类继承(因为接口不能被类 extends),但可以 extends 其他接口——前提是扩展后仍只保留一个抽象方法。
- 若接口 A 是函数式接口,接口 B extends A,那么 B 必须不添加新抽象方法,否则 B 就不再是函数式接口
- 常见做法是让基础函数式接口(如
Function<t></t>)作为根,再通过 extends 定义更具体的变体(如ToIntFunction<t></t>是独立接口,不继承Function,因其抽象方法签名不同) - 错误示例:
interface Bad extends Runnable, Comparable<string> { }</string>—— 含两个抽象方法(run()和compareTo()),编译报错
用默认方法增强能力,不破坏函数式契约
函数式接口可通过 default 方法提供通用行为,这是安全扩展的关键方式。这些方法不能改变“单抽象方法”本质,但能提升复用性与链式调用能力。
-
Function<t></t>提供andThen()和compose(),都是 default 方法,不新增抽象方法 - 自定义时可添加类似逻辑:
default T orElse(T fallback) { return this.apply() != null ? this.apply() : fallback; }(需注意避免副作用) - 所有 default 方法应基于唯一抽象方法实现,确保语义一致
优先复用 JDK 标准函数式接口,避免重复造轮子
Java 8+ 已提供覆盖大多数场景的函数式接口(Consumer、Supplier、Predicate、各类 Function 及其原始类型特化版)。自行设计前先确认是否已有匹配语义的现成接口。
- 例如处理“字符串 → 整数转换并校验”:用
Function<string integer></string>+Predicate<integer></integer>组合,比新建StringToIntValidator更灵活 - 命名应反映用途而非技术细节:
FilterCondition<user></user>比UserPredicate更具业务表达力,但仍建议直接用Predicate<user></user>并配以清晰变量名(如activeUserFilter) - 若真需新接口,确保其抽象方法签名不可被现有接口替代(如需要三参数输入:用
TriFunction<a></a>而非强行塞进BiFunction)
组合优于继承:用函数拼接代替接口层级
函数式编程强调行为组合。与其设计多层接口继承(如 ValidatingFunction ← LoggingFunction ← BaseFunction),不如用高阶函数封装逻辑:
- 用装饰器模式包装:传入一个
Function<x></x>,返回增强后的Function<x></x> - 示例:
static <t> Function<t t> logBefore(Function<t t> f) { return t -> { System.out.println("before: " + t); return f.apply(t); }; }</t></t></t> - 这样既保持接口扁平,又支持运行时动态装配,比静态继承链更灵活、更易测试
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











