概述
默认方法让你可以为自己的库中的接口添加新功能,并且确保它与基于原有的老接口编写的代码在二进制上相互兼容。
我们从一个简单的接口开始
定义一个接口,这个接口用于描述钟表的功能——显示时间。
public interface Clock {
void showTime();
}
基于这个接口,我们定义了一个古代时钟。
public class OldenClock implements Clock {
@Override
public void showTime() {
System.out.println("CurrentTime: 19:33:09");
}
}
假如有一天我们需要在所有时钟都需要添加一个新的功能——显示日期。于是,我们在原有的接口上添加新功能:
public interface Clock {
void showTime();
void showDate();
}
但是,原有的接口实现的代码已经存在了。名为OldenClock的这个类已经编写完成,如果我们将接口直接变更,那么就需要重新编写OldenClock的代码,实现showDate()方法才行。很显然这是不划算的,对于这种问题,我们可以有两种解决办法。
方法一:接口继承
重新定义一个时钟接口,名为DateClock,该接口继承Clock接口即可。
public interface DateClock extends Clock {
void showDate();
}
这样,DateClock的接口就会继承Clock原有的两个方法,而具有三个方法,正好符合我们的需求。我们可以基于这个类实现一个西方时钟的类。
public class WestClock implements DateClock {
@Override
public void showTime() {
System.out.println("CurrentTime: 19:33:09");
}
@Override
public void showDate() {
System.out.println("CurrentDate: 2020-09-18");
}
}
方法二:默认方法
有没有办法,在不定义新接口的情况下完成上述的需求呢。答案是:有。我们将原有的Clock接口的定义更改一下:
public interface Clock {
void showTime();
default void showDate(){
System.out.println("CurrentDate: 2020-09-18");
}
}
在这个方法中,我们添加一个使用default访问标识符标记的名为showDate的方法,我们都知道接口中的方法都是不允许有方法体的,但是default标记的默认方法却是可以的。
使用default方法就可以解决修改接口,而不影响原有接口实现类的。