当前位置: 首页 > news >正文

《Java 程序设计》第 10 章 - 接口与 Lambda 表达式

        大家好!今天我们来学习 Java 中的接口与 Lambda 表达式。这两个特性在 Java 编程中非常重要,尤其是 Lambda 表达式,它是 Java 8 引入的新特性,极大地简化了代码编写。话不多说,让我们开始吧!

思维导图

10.1 接口

10.1.1 接口定义

接口(interface)是纯粹的抽象类型,所有成员默认 public(JDK 8 以前)。
语法:

[public] interface 接口名 [extends 父接口列表] {// 1. 抽象方法(可省略 public abstract)返回类型 方法名(参数列表);// 2. 常量(默认 public static final)类型 常量名 = 值;
}

10.1.2 接口的实现

类通过 implements 关键字实现接口,必须实现所有抽象方法
示例:

// 文件:Drawable.java
public interface Drawable {void draw();        // 抽象方法String DEFAULT_COLOR = "BLACK"; // 常量
}// 文件:Circle.java
public class Circle implements Drawable {private double r;public Circle(double r) { this.r = r; }@Overridepublic void draw() {System.out.println("画一个半径为 " + r + " 的圆,颜色:" + DEFAULT_COLOR);}public static void main(String[] args) {new Circle(3.5).draw();}
}

10.1.3 接口的继承

接口可多重继承,形成“继承链”。

interface A { void a(); }
interface B { void b(); }
interface C extends A, B { void c(); } // C 拥有 a() b() c()

10.1.4 接口类型的使用

接口变量可指向任何实现类对象——多态的核心。

Drawable d = new Circle(2);
d.draw();           // 运行时调用 Circle 的实现

10.1.5 常量

接口中的变量默认 public static final,一般用于全局常量池


10.2 静态方法和默认方法

10.2.1 静态方法

JDK 8 起允许接口定义 static 方法只能通过接口名调用

public interface Logger {static void info(String msg) {System.out.println("[INFO] " + msg);}
}
// 调用
Logger.info("系统启动");

10.2.2 默认方法

default 方法提供默认实现,实现类可重写也可直接使用

public interface Animal {default void breathe() {System.out.println("用肺呼吸");}
}

10.2.3 解决默认方法冲突

当类实现的多个接口出现同名默认方法时,遵循以下规则:

  1. 类优先(优先选择父类的方法);

  2. 否则必须手动重写,使用 接口名.super.方法() 指定。

interface A {default void hello() { System.out.println("A"); }
}
interface B {default void hello() { System.out.println("B"); }
}
class C implements A, B {@Overridepublic void hello() {A.super.hello(); // 显式指定}
}

10.3 接口示例

10.3.1 Comparable 接口

让对象具备自然排序能力。

import java.util.*;public class Student implements Comparable<Student> {private String name;private int score;public Student(String name, int score) {this.name = name;this.score = score;}@Overridepublic int compareTo(Student o) {return Integer.compare(this.score, o.score); // 升序}@Overridepublic String toString() {return name + ":" + score;}public static void main(String[] args) {// 1. 用 new ArrayList<>(...) 包装,变成可变列表List<Student> list = new ArrayList<>(List.of(new Student("Alice", 90),new Student("Bob", 70),new Student("Carol", 95)));// 2. 排序Collections.sort(list);// 3. 打印list.forEach(System.out::println);}
}

10.3.2 Comparator 接口

当需要多种排序策略时使用,更灵活。

// 文件:Student.java
import java.util.*;public class Student implements Comparable<Student> {private String name;private int score;public Student(String name, int score) {this.name = name;this.score = score;}/* ===== 新增 getter ===== */public String getName() { return name; }public int getScore()   { return score; }@Overridepublic int compareTo(Student o) {return Integer.compare(this.score, o.score); // 自然排序:分数升序}@Overridepublic String toString() {return name + ":" + score;}
}
// 文件:StudentComparator.java
import java.util.*;public class StudentComparator {public static void main(String[] args) {// 用 new ArrayList<>(...) 把不可变列表变成可变List<Student> list = new ArrayList<>(List.of(new Student("Alice", 90),new Student("Bob", 70),new Student("Carol", 95)));// 1. 按姓名升序list.sort(Comparator.comparing(Student::getName));System.out.println("按姓名升序:");list.forEach(System.out::println);// 2. 按分数降序list.sort(Comparator.comparingInt(Student::getScore).reversed());System.out.println("按分数降序:");list.forEach(System.out::println);}
}

10.4 Lambda 表达式

10.4.1 Lambda 简介

Lambda 是匿名函数,用于简化函数式接口的实例化

10.4.2 函数式接口

仅含一个抽象方法的接口,可用 @FunctionalInterface 标注

10.4.3 Lambda 语法

(parameters) -> { statements }

10.4.4 预定义的函数式接口

接口名抽象方法用途示例
Predicate<T>boolean test(T t)过滤
Function<T,R>R apply(T t)转换
Consumer<T>void accept(T t)消费
Supplier<T>T get()生产

10.4.5 方法引用与构造方法引用

  • 方法引用:类::方法

  • 构造引用:类::new

示例:使用 Lambda + 方法引用过滤列表

import java.util.*;
import java.util.function.Predicate;public class LambdaDemo {public static void main(String[] args) {List<String> list = Arrays.asList("Java", "Python", "Go", "C++");// 1. 匿名类Predicate<String> p1 = new Predicate<String>() {@Overridepublic boolean test(String s) {return s.length() > 3;}};// 2. LambdaPredicate<String> p2 = s -> s.length() > 3;// 3. 方法引用Predicate<String> p3 = LambdaDemo::isLongName;list.stream().filter(p3).forEach(System.out::println);}private static boolean isLongName(String s) {return s.length() > 3;}
}

10.5 小结

  • 接口:解耦、多继承、常量池;

  • 默认/静态方法:增强接口能力;

  • Comparable & Comparator:两种排序策略;

  • Lambda:函数式编程利器,简化代码。


编程练习

练习 1:员工薪资处理(接口 + Lambda)

需求:

  1. 定义接口 Payabledouble calcSalary()

  2. SalariedEmployee(固定工资)、HourlyEmployee(时薪)实现接口;

  3. 用 Lambda 计算全体员工总薪资并过滤高薪员工(> 20000)。

完整代码:

// 文件:Payable.java
@FunctionalInterface
public interface Payable {double calcSalary();
}// 文件:SalariedEmployee.java
public class SalariedEmployee implements Payable {private double monthSalary;public SalariedEmployee(double monthSalary) {this.monthSalary = monthSalary;}@Overridepublic double calcSalary() {return monthSalary;}@Overridepublic String toString() {return "SalariedEmployee: " + monthSalary;}
}// 文件:HourlyEmployee.java
public class HourlyEmployee implements Payable {private double hours;private double rate;public HourlyEmployee(double hours, double rate) {this.hours = hours;this.rate = rate;}@Overridepublic double calcSalary() {return hours * rate;}@Overridepublic String toString() {return "HourlyEmployee: " + calcSalary();}
}// 文件:PayrollSystem.java
import java.util.*;
import java.util.stream.Collectors;public class PayrollSystem {public static void main(String[] args) {List<Payable> employees = List.of(new SalariedEmployee(18000),new HourlyEmployee(160, 100),new SalariedEmployee(25000),new HourlyEmployee(200, 120));// 总薪资double total = employees.stream().mapToDouble(Payable::calcSalary).sum();System.out.println("总薪资 = " + total);// 高薪员工List<Payable> high = employees.stream().filter(e -> e.calcSalary() > 20000).collect(Collectors.toList());high.forEach(System.out::println);}
}

运行结果:

① 思维导图:接口与 Lambda 学习路线

② 接口继承关系类图(PlantUML)

@startuml
interface Drawable
interface Colorable
interface Paintable extends Drawable, Colorable
class Circle implements Paintable
@enduml

③ Lambda 表达式执行流程图


结语

复制代码直接 javac *.java 即可体验。欢迎评论区交流!

http://www.lryc.cn/news/604960.html

相关文章:

  • 锁定中科院1区TOP!融合LSTM与Attention做时间序列预测 !
  • 新手向:DeepSeek 部署中的常见问题及解决方案
  • 【OD机试题解法笔记】符号运算
  • [特殊字符] 征服CPU的艺术:Rust多进程编程实战指南
  • AI绘画模型生成 MZ 日系美感人像/极致cos
  • 拥抱智慧物流时代:数字孪生技术的应用与前景
  • 小红书笔记详情API指南
  • VS调试前端项目时老是弹出Chrome无法更新的提示
  • Gitee Wiki重塑关键领域软件开发的知识管理范式
  • makefile中include *.d文件的作用
  • Git 中复原 revert 和重设 reset 有什么区别?
  • 认识ansible(入门)
  • uni-app,uni.navigateTo
  • 赵义弘-----补题报告
  • 开源项目:排序算法的多种实现方式
  • vue3 实现下载指令
  • 【通识】操作系统
  • Python 程序设计讲义(45):组合数据类型——集合类型:集合的常用操作
  • jni理解
  • 网络编程-(网络计算机和网络通信)
  • Adobe Illustrator安装下载教程(附安装包)Illustrator2025
  • 【异世界历险之数据结构世界(冒泡、选择、快速排序)】
  • 数据结构(7)单链表算法题OVA
  • LLM 模型部署难题的技术突破:从轻量化到分布式推理的全栈解决方案
  • 【数据结构初阶】--二叉树(五)
  • 数据结构——单链表1
  • jmeter读取上游接口并遍历数组数据并进行压测
  • Vulnhub靶场:ica1
  • 【网络运维】 Linux:使用 Cockpit 管理服务器
  • IO复用实现并发服务器