Java8——接口的默认方法和静态方法
Java8接口新特性
interface 的设计初衷是面向抽象,提高扩展性。但缺点就是Interface 修改的时候,实现它的类也必须跟着修改。
为了解决接口的修改与现有的实现不兼容的问题。Java 8在接口声明的时候增加了两个新的概念:默认和静态方法。
新 interface 的方法可以用default?或?static修饰,一个 interface 中可以有多个方法被它们修饰,这 2 个修饰符的区别主要也是普通方法和静态方法的区别。
- default修饰的方法,是普通实例方法,可以用this调用,可以被子类继承、重写。
- static修饰的方法,使用上和一般类静态方法一样。但它不能被子类继承,只能用Interface调用。
默认方法允许我们在接口里添加新的方法,而不会破坏实现这个接口的已有类的兼容性,也就是说不会强迫实现接口的类实现默认方法。
默认方法和抽象方法的区别是抽象方法必须要被实现,默认方法不是。作为替代方式,接口可以提供一个默认的方法实现,所有这个接口的实现类都会通过继承得到这个方法(如果有需要也可以重写这个方法)
我们来看一个实际的例子。
public interface InterfaceNew {
default void def() {
System.out.println("interface default方法");
}
}
public interface InterfaceNewImpl1 implements InterfaceNew{
}
public interface InterfaceNewImpl2 implements InterfaceNew{
public void def() {
System.out.println("interface InterfaceNewImpl2方法");
}
}
接口InterfaceNew使用default关键字声明了一个默认方法def(),类InterfaceNewImpl1实现了InterfaceNew接口,没有对默认方法做任何修改。另外一个类InterfaceNewImpl2重写类默认实现,提供了自己的实现方法。
Java 8 的另外一个有意思的新特性是接口里可以声明静态方法,并且可以实现。例子如下:
public interface InterfaceNew {
static void sm() {
System.out.println("interface提供的方式实现");
}
}
下面是把接口的静态方法和默认方法放在一起的示例:
public interface InterfaceNew {
default void def() {
System.out.println("interface default方法");
}
default void def2() {
System.out.println("interface default2方法");
}
static void sm() {
System.out.println("interface提供的方式实现");
}
static void sm2() {
System.out.println("interface提供的方式实现");
}
//需要实现类重写
void f();
}
public interface InterfaceNew1 {
default void def() {
System.out.println("InterfaceNew1 default方法");
}
}
如果有一个类既实现了 InterfaceNew 接口又实现了 InterfaceNew1接口,它们都有def(),并且 InterfaceNew 接口和InterfaceNew1接口没有继承关系的话,这时就必须重写def()。不然的话,编译的时候就会报错。
public class InterfaceNewImpl implements InterfaceNew , InterfaceNew1{
public static void main(String[] args) {
InterfaceNewImpl interfaceNew = new InterfaceNewImpl();
interfaceNew.def();
}
@Override
public void def() {
InterfaceNew1.super.def();
}
@Override
public void f() {
}
}
JVM平台的接口的默认方法实现是很高效的,并且方法调用的字节码指令支持默认方法。默认方法使已经存在的接口可以修改而不会影响编译的过程。java.util.Collection中添加的额外方法就是最好的例子:stream(),?parallelStream(),?forEach(),?removeIf()
在Java8 中接口和抽象类有什么区别的?
很多小伙伴认为:“既然 interface 也可以有自己的方法实现,似乎和 abstract class 没多大区别了。”
其实它们还是有区别的:
- 接口是多实现,而抽象类是单继承
- 接口的方法是 public abstract 修饰,变量是 public static final 修饰。 而抽象类可以用其他修饰符
- 接口的方法是更像是一个扩展插件。而抽象类的方法是要继承的。
开始我们也提到,interface 新增default和static修饰的方法,为了解决接口的修改与现有的实现不兼容的问题,并不是为了要替代abstract class。在使用上,该用 abstract class 的地方还是要用 abstract class,不要因为 interface 的新特性而将之替换。
参考:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!