

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

接口(interface)是纯粹的抽象类型,所有成员默认 public(JDK 8 以前)。
语法:
[public] interface 接口名 [extends 父接口列表] {
// 1. 抽象方法(可省略 public abstract)
返回类型 方法名(参数列表);
// 2. 常量(默认 public static final)
类型 常量名 = 值;
}类通过 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; }
@Override
public void draw() {
System.out.println("画一个半径为 " + r + " 的圆,颜色:" + DEFAULT_COLOR);
}
public static void main(String[] args) {
new Circle(3.5).draw();
}
}
接口可多重继承,形成“继承链”。
interface A { void a(); }
interface B { void b(); }
interface C extends A, B { void c(); } // C 拥有 a() b() c()接口变量可指向任何实现类对象——多态的核心。
Drawable d = new Circle(2);
d.draw(); // 运行时调用 Circle 的实现接口中的变量默认 public static final,一般用于全局常量池。
JDK 8 起允许接口定义 static 方法,只能通过接口名调用。
public interface Logger {
static void info(String msg) {
System.out.println("[INFO] " + msg);
}
}
// 调用
Logger.info("系统启动");default 方法提供默认实现,实现类可重写也可直接使用。
public interface Animal {
default void breathe() {
System.out.println("用肺呼吸");
}
}当类实现的多个接口出现同名默认方法时,遵循以下规则:
接口名.super.方法() 指定。
interface A {
default void hello() { System.out.println("A"); }
}
interface B {
default void hello() { System.out.println("B"); }
}
class C implements A, B {
@Override
public void hello() {
A.super.hello(); // 显式指定
}
}让对象具备自然排序能力。
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;
}
@Override
public int compareTo(Student o) {
return Integer.compare(this.score, o.score); // 升序
}
@Override
public 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);
}
}
当需要多种排序策略时使用,更灵活。
// 文件: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; }
@Override
public int compareTo(Student o) {
return Integer.compare(this.score, o.score); // 自然排序:分数升序
}
@Override
public 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);
}
}
Lambda 是匿名函数,用于简化函数式接口的实例化。
仅含一个抽象方法的接口,可用 @FunctionalInterface 标注。
(parameters) -> { statements }
接口名 | 抽象方法 | 用途示例 |
|---|---|---|
Predicate<T> | boolean test(T t) | 过滤 |
Function<T,R> | R apply(T t) | 转换 |
Consumer<T> | void accept(T t) | 消费 |
Supplier<T> | T get() | 生产 |
类::方法
类::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>() {
@Override
public boolean test(String s) {
return s.length() > 3;
}
};
// 2. Lambda
Predicate<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;
}
}
需求:
Payable 含 double calcSalary();
SalariedEmployee(固定工资)、HourlyEmployee(时薪)实现接口;
完整代码:
// 文件: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;
}
@Override
public double calcSalary() {
return monthSalary;
}
@Override
public 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;
}
@Override
public double calcSalary() {
return hours * rate;
}
@Override
public 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);
}
}运行结果:


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

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