java8之前接口中的方法默认类型都是public abstract,也就是抽象方法,具体实现都交给实现类。而java8对接口功能做了增强,增加了default方法和static方法,也就是说从java8开始接口中的方法不再只能是抽象的,也可以有实现。
其应用也非常简单,如下面的例子所示,在接口中定义default和static方法:
public interface DefaultInterface {
// default方法
default void defaultFunction(){
System.out.println("this is a default function");
}
// static方法
static void staticFunction(){
System.out.println("this is a static funcion");
}
}
在实现类中可以直接调用接口的default方法,通过接口名.方法名调用static方法:
public class DefaultInterfaceImpl implements DefaultInterface{
public static void main(String[] args){
// 调用default方法
new DefaultInterfaceImpl().defaultFunction();
// 调用static方法
DefaultInterface.staticFunction();
}
}
运行结果如下:
注意点:
- 实现类可以重写default方法,不能重写static方法
- 如果一个类实现了两个接口,而这两个接口拥有相同方法签名(相同的方法名、参数)、返回类型的default方法时,实现类就必须重写该default方法,否则编译器会因为不知道应该调用哪一个接口中的default方法而报错。重写接口中default方法后,编译器会执行重写后的方法。不过好的编程习惯是明智的选择方法名,避免和其它接口产生冲突。
- 如果一个类同时继承了一个类和实现了一个或多个接口,而父类中拥有和接口中default方法相同的签名、返回值的方法时,当该类未重写该方法,直接调用时,将会调用父类中的方法。
新特性带来的好处:
- 增加default方法,可以在不破坏java现有实现架构的情况下能往接口里增加新方法。
尽管如此,还是不推荐过度使用,如果你大量使用default方法在你的应用接口中,你将很快意识到他没有真正精简代码。因为你不能在接口中提炼default里重复的代码到一个新的普通方法,这与以精简代码为目的的default关键字相冲突。不过这个问题在java9中通过在接口中支持private interface methods得到解决。 - 而static方法除了调用比较方便外还有一个有趣的意义,程序入口main方法也是static,现在在接口也可以运行了。
接口和抽象类:
如此看来接口是不是和类越来越接近了?那么回归到一道基础的面试题:现在接口和抽象类有什么区别呢?
- 一个类只能继承一个抽象类,却可以实现多个接口。
- 虽然接口和抽象类都不能被实例化,但是抽象类可以有构造器,接口没有构造器。
- 抽象类中方法可以有public、protected、默认(包)甚至private范围的方法,接口只能有public范围的方法(即使是default也是public范围的,当然从java9开始接口也可以有private方法 。