Java,举例说明,函数式接口,函数式接口实现类,通过匿名内部类实现函数式接口,通过 Lambda 表达式实现函数式接口,演变的过程

Java,举例说明,函数式接口,函数式接口实现类,通过匿名内部类实现函数式接口,通过 Lambda 表达式实现函数式接口,演变的过程

1. 什么是函数式接口 (Functional Interface)?

函数式接口是 只包含一个抽象方法 的接口。它可以用 Lambda 表达式、方法引用或构造器引用进行实例化。

为了明确表示一个接口是函数式接口,通常使用 @FunctionalInterface 注解(非强制,但推荐)。

示例:定义一个简单的函数式接口

java 复制代码
@FunctionalInterface
public interface GreetingService {
    // 只有一个抽象方法
    void greet(String name);

    // 可以有默认方法和静态方法,不影响其作为函数式接口
    default void sayGoodbye() {
        System.out.println("Goodbye!");
    }
}

2. 函数式接口的实现类

你可以像普通接口一样,创建一个具体的实现类来实现这个接口。

示例:通过普通类实现函数式接口

java 复制代码
// 实现类
class EnglishGreeting implements GreetingService {
    @Override
    public void greet(String name) {
        System.out.println("Hello, " + name);
    }
}

// 使用
public class Main {
    public static void main(String[] args) {
        GreetingService service = new EnglishGreeting();
        service.greet("Alice"); // 输出: Hello, Alice
    }
}

这种方式虽然可行,但在需要传递简单行为逻辑的场景下显得繁琐。


3. 通过匿名内部类 (Anonymous Inner Class) 实现函数式接口

在 Lambda 表达式出现之前,如果需要在代码中直接提供接口的实现,最常用的方式就是匿名内部类。

示例:使用匿名内部类

java 复制代码
public class Main {
    public static void main(String[] args) {
        // 创建一个匿名内部类来实现 GreetingService 接口
        GreetingService service = new GreetingService() {
            @Override
            public void greet(String name) {
                System.out.println("Hello from anonymous class, " + name);
            }
        };

        service.greet("Bob"); // 输出: Hello from anonymous class, Bob
    }
}
  • 优点:可以在需要时就地创建实现,无需预先定义一个类。
  • 缺点 :代码冗长,包含了很多样板代码(new GreetingService() { ... }@Override),可读性较差。

4. 通过 Lambda 表达式 (Lambda Expression) 实现函数式接口

Lambda 表达式是 Java 8 引入的语法糖,它为函数式接口提供了更简洁、更优雅的实现方式。它的核心思想是"把功能(行为)当作参数"传递。

语法(parameters) -> { body }

演变过程

  1. 原始匿名内部类

    java 复制代码
    GreetingService service = new GreetingService() {
        @Override
        public void greet(String name) {
            System.out.println("Hello, " + name);
        }
    };
  2. 简化第一步:去掉外部结构

    因为编译器知道 GreetingService 是一个函数式接口,且只接受一个 String 参数,所以可以省略 new GreetingService()@Override 和方法名。

    java 复制代码
    // Lambda 表达式
    GreetingService service = (String name) -> {
        System.out.println("Hello, " + name);
    };
  3. 简化第二步:类型推断

    编译器可以从上下文 (GreetingService 接口的 greet 方法签名) 推断出 name 的类型是 String,因此可以省略参数类型。

    java 复制代码
    GreetingService service = (name) -> {
        System.out.println("Hello, " + name);
    };
  4. 简化第三步:单个参数的括号

    如果 Lambda 表达式只有一个参数,且类型已知,可以省略参数外的括号。

    java 复制代码
    GreetingService service = name -> {
        System.out.println("Hello, " + name);
    };
  5. 简化第四步:单行表达式体

    如果 Lambda 的主体只有一条语句,可以省略大括号 {}return 关键字(如果有返回值的话)。

    java 复制代码
    // 最终形态
    GreetingService service = name -> System.out.println("Hello, " + name);

完整示例:使用 Lambda 表达式

java 复制代码
import java.util.Arrays;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        // 使用 Lambda 表达式创建实现
        GreetingService service = name -> System.out.println("Hello, " + name);

        service.greet("Charlie"); // 输出: Hello, Charlie

        // --- Lambda 在实际应用中的强大之处 ---
        List<String> names = Arrays.asList("Alice", "Bob", "Charlie");

        // 将 Lambda 表达式作为参数传递给 forEach 方法
        // forEach 方法接收一个 Consumer<T> 类型的函数式接口
        names.forEach(name -> System.out.println(name));
        // 上面这行代码等价于匿名内部类:
        /*
        names.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });
        */
    }
}

总结:演变的核心思想

这个演变过程体现了从面向对象编程 (OOP)函数式编程 (FP) 思想的融合。

  • 传统 OOP 方式:必须先创建一个类,然后实例化该类的对象来执行特定行为。
  • 匿名内部类 :简化了 OOP 的流程,在需要的地方直接定义行为,但仍带有 OOP 的痕迹(如 new, @Override)。
  • Lambda 表达式 :彻底将行为本身(函数)作为第一等公民,直接传递给需要的地方,代码更加简洁、聚焦于"做什么"而非"如何做"。

这种演变极大地提高了代码的可读性和表达力,特别是在处理集合、事件监听等场景中。

相关推荐
码兄科技6 小时前
Java AI智能体开发实战:从零构建智能对话系统指南
java·开发语言·人工智能
折哥的程序人生 · 物流技术专研7 小时前
第8篇:六大设计原则在工厂模式中的体现
java·设计模式·设计原则·工厂模式·编程进阶·扩充系列
小明bishe188 小时前
计算机毕业设计之基于JAVA的植物科普网站
java·spring boot·spring·架构·课程设计
Drone_xjw8 小时前
从 GDB 到 CDB:C/C++ 程序调试的两把“手术刀”
c语言·开发语言·c++
r_oo_ki_e_8 小时前
Java Map 集合学习笔记
java·笔记·学习
SL-staff8 小时前
智慧园区2000+设备统一管理:JVS-IoT如何降低运维成本40%
java·开发语言·物联网·智慧园区·设备管理·运维优化·jvs-iot
聪明的一休丶9 小时前
VLLM v0.24.0 版本深度解析:新引擎、新架构与大规模服务全家桶升级
python·架构·vllm
咖啡八杯9 小时前
GoF设计模式——模板方法模式
java·后端·spring·设计模式
爱笑的源码基地9 小时前
一款全开源的信创云PACS影像云平台解决方案,支持多模态医学影像处理(CT/MR/DR/超声/病理等)
java·源码·国产化·pacs·云影像·区域pacs