接口中的默认方法和静态方法
本课属于 Coddy Java 学习旅程的“面向对象编程”单元。第 37 课,共 87 课。
最初,接口只能包含没有实现的抽象方法。从 Java 8 开始,接口可以包含默认方法和静态方法,因此更加灵活。
默认方法使用 default 关键字直接在接口中提供实现。实现该接口的类会自动继承此行为,但可根据需要重写它:
public interface Drawable {
void draw();
default void display() {
System.out.println("Displaying on screen...");
draw();
}
}任何实现 Drawable 的类都可以免费获得 display() 方法。这对于向现有接口添加新方法特别有用,而且不会破坏已经实现这些接口的类。
接口中的静态方法与类中的静态方法作用相同。它们属于接口本身,并通过接口名称调用:
public interface MathOperations {
static int add(int a, int b) {
return a + b;
}
}
// 用法
int result = MathOperations.add(5, 3);静态接口方法不能被重写,也不会被实现类继承。它们适合用作与接口用途相关的实用方法。
如果一个类实现了两个具有相同默认方法签名的接口,就必须重写该方法来解决冲突。
挑战
简单让我们构建一个消息系统,展示接口中的默认方法和静态方法。你将创建一个带有内置功能的接口,实现它的类可以直接使用这些功能,也可以根据需要进行自定义。
你将把代码分成四个文件:
Messenger.java:定义一个表示任意消息服务的接口。声明一个返回 void 的抽象方法sendMessage(String message)。添加一个名为sendWithTimestamp(String message)的默认方法,让它打印:[TIMESTAMP],然后调用sendMessage(message)。此外,还要添加一个名为formatMessage(String message)的静态方法,让它返回转换为大写的消息。EmailMessenger.java:创建一个实现Messenger的类。它有一个recipient字段(String)。添加一个用于初始化收件人的构造函数。实现sendMessage(),让它打印:Email to [recipient]: [message]。这个类直接使用默认的sendWithTimestamp()方法。SMSMessenger.java:再创建一个实现Messenger的类。它有一个phoneNumber字段(String)。添加一个用于初始化电话号码的构造函数。实现sendMessage(),让它打印:SMS to [phoneNumber]: [message]。重写默认的sendWithTimestamp()方法,让它打印:[URGENT],然后调用sendMessage(message),而不是使用默认的时间戳行为。Main.java:把所有内容组合起来,展示接口中的默认方法和静态方法。你会收到三个输入:电子邮件收件人、电话号码和消息。首先,使用静态方法Messenger.formatMessage()格式化消息并保存。然后,创建一个 EmailMessenger 和一个 SMSMessenger。对于每个消息器,使用格式化后的消息调用sendWithTimestamp():注意,EmailMessenger 使用默认实现,而 SMSMessenger 使用它重写后的版本。
你会收到三个输入:电子邮件收件人(String)、电话号码(String)和消息(String)。
输出总共应有四行,每个消息器占两行:一行是前缀([TIMESTAMP] 或 [URGENT]),另一行是消息。EmailMessenger 会显示默认的时间戳前缀,而 SMSMessenger 会显示自定义的紧急前缀!两者使用的都是经过静态方法格式化(转换为大写)的消息!
亲手试试
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 读取输入
String emailRecipient = scanner.nextLine();
String phoneNumber = scanner.nextLine();
String message = scanner.nextLine();
// TODO: 使用 Messenger.formatMessage() 格式化消息并保存
// TODO: 使用邮件收件人创建 EmailMessenger
// TODO: 使用电话号码创建 SMSMessenger
// TODO: 在 EmailMessenger 上调用 sendWithTimestamp(),传入格式化后的消息
// TODO: 在 SMSMessenger 上调用 sendWithTimestamp(),传入格式化后的消息
}
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Java 在线编译器