本文目录导读:

Java接口的默认方法(default method)是Java 8引入的特性,允许在接口中定义带有方法体的方法,下面通过几个案例来说明如何使用:
案例1:基本使用
// 定义接口
interface Vehicle {
// 抽象方法
void start();
// 默认方法
default void honk() {
System.out.println("车辆鸣笛:滴滴!");
}
// 静态方法(也是Java 8新特性)
static void service() {
System.out.println("车辆保养");
}
}
// 实现类
class Car implements Vehicle {
@Override
public void start() {
System.out.println("汽车启动");
}
// 可以选择重写默认方法
@Override
public void honk() {
System.out.println("汽车鸣笛:叭叭!");
}
}
// 另一个实现类
class Bike implements Vehicle {
@Override
public void start() {
System.out.println("自行车启动");
}
// 不重写honk方法,使用默认实现
}
// 测试
public class DefaultMethodDemo {
public static void main(String[] args) {
Car car = new Car();
car.start(); // 输出:汽车启动
car.honk(); // 输出:汽车鸣笛:叭叭!
Bike bike = new Bike();
bike.start(); // 输出:自行车启动
bike.honk(); // 输出:车辆鸣笛:滴滴!
// 调用静态方法
Vehicle.service(); // 输出:车辆保养
}
}
案例2:解决“钻石问题”
// 接口A
interface A {
default void show() {
System.out.println("A的show方法");
}
}
// 接口B
interface B {
default void show() {
System.out.println("B的show方法");
}
}
// 接口C继承A和B
interface C extends A, B {
// 必须重写show方法,解决冲突
@Override
default void show() {
// 可以选择调用其中一个父接口的方法
A.super.show(); // 调用A的show方法
B.super.show(); // 调用B的show方法
System.out.println("C的show方法");
}
}
// 实现类
class MyClass implements C {
// 可以重写show方法,也可以不重写
}
// 测试
public class DiamondProblemDemo {
public static void main(String[] args) {
MyClass obj = new MyClass();
obj.show();
// 输出:
// A的show方法
// B的show方法
// C的show方法
}
}
案例3:集合框架中的实用场景
import java.util.ArrayList;
import java.util.List;
// 自定义集合接口
interface MyCollection<T> {
void add(T item);
T get(int index);
int size();
// 默认方法:批量添加
default void addAll(T... items) {
for (T item : items) {
add(item);
}
}
// 默认方法:检查是否为空
default boolean isEmpty() {
return size() == 0;
}
// 默认方法:清空集合
default void clear() {
while (!isEmpty()) {
remove(size() - 1);
}
}
// 新增的抽象方法
void remove(int index);
}
// 实现类
class SimpleList<T> implements MyCollection<T> {
private List<T> list = new ArrayList<>();
@Override
public void add(T item) {
list.add(item);
}
@Override
public T get(int index) {
return list.get(index);
}
@Override
public int size() {
return list.size();
}
@Override
public void remove(int index) {
list.remove(index);
}
}
// 测试
public class CollectionDemo {
public static void main(String[] args) {
SimpleList<String> list = new SimpleList<>();
// 使用默认方法
list.addAll("Java", "Python", "C++"); // 批量添加
System.out.println("列表是否为空: " + list.isEmpty()); // 输出:false
System.out.println("列表大小: " + list.size()); // 输出:3
list.clear();
System.out.println("清空后大小: " + list.size()); // 输出:0
}
}
案例4:日志记录功能
interface Logger {
// 抽象方法
void log(String message);
// 默认方法:提供不同级别的日志
default void info(String message) {
log("[INFO] " + message);
}
default void warning(String message) {
log("[WARNING] " + message);
}
default void error(String message) {
log("[ERROR] " + message);
}
// 默认方法:记录异常
default void error(Exception e) {
log("[ERROR] " + e.getMessage());
logStackTrace(e);
}
// 私有方法(Java 9+)
private void logStackTrace(Exception e) {
for (StackTraceElement element : e.getStackTrace()) {
log(" at " + element.toString());
}
}
}
// 控制台日志实现
class ConsoleLogger implements Logger {
@Override
public void log(String message) {
System.out.println(message);
}
}
// 文件日志实现
class FileLogger implements Logger {
@Override
public void log(String message) {
// 简化:实际应该写入文件
System.out.println("写入文件: " + message);
}
}
// 测试
public class LoggerDemo {
public static void main(String[] args) {
Logger console = new ConsoleLogger();
console.info("应用启动");
console.warning("资源不足");
console.error("网络连接失败");
System.out.println("---");
Logger file = new FileLogger();
try {
throw new RuntimeException("测试异常");
} catch (RuntimeException e) {
file.error(e);
}
}
}
使用建议
- 向后兼容:默认方法主要用于向现有接口添加新功能而不破坏已有实现
- 模板方法:提供共同的行为实现
- 可选功能:实现类可以选择性重写
- 避免过度使用:默认方法应该提供通用的、合理的默认实现
默认方法使得Java接口更加灵活,可以在不破坏现有代码的情况下扩展接口功能。