Java学习笔记(51)——Java8之默认方法(虚拟扩展方法)

Java里边的默认方法跟C#里边的扩展方法是一回事儿,只是没有C#做的优雅罢了,因为要修改接口,而C#是新增静态类!

什么是默认方法,为什么要有默认方法

简单说,就是接口可以有实现方法,而且不需要实现类去实现其方法。只需在方法名前面加个default关键字即可。 

为什么要有这个特性?首先,之前的接口是个双刃剑,好处是面向抽象而不是面向具体编程,缺陷是,当需要修改接口时候,需要修改全部实现该接口的类,目前的java 8之前的集合框架没有foreach方法,通常能想到的解决办法是在JDK里给相关的接口添加新的方法及实现。然而,对于已经发布的版本,是没法在给接口添加新方法的同时不影响已有的实现。所以引进的默认方法。他们的目的是为了解决接口的修改与现有的实现不兼容的问题。

简单的例子

一个接口A,Clazz类实现了接口A。

public interface A {
    default void foo(){
       System.out.println("Calling A.foo()");
    }
}
   
public class Clazz implements A {
    public static void main(String[] args){
       Clazz clazz = new Clazz();
       clazz.foo();//调用A.foo()
    }
}

代码是可以编译的,即使Clazz类并没有实现foo()方法。在接口A中提供了foo()方法的默认实现。

java 8抽象类与接口对比

这一个功能特性出来后,很多同学都反应了,java 8的接口都有实现方法了,跟抽象类还有什么区别?其实还是有的,请看下表对比。

114052_lgVH_2315986.png

多重继承的冲突说明

由于同一个方法可以从不同接口引入,自然而然的会有冲突的现象,默认方法判断冲突的规则如下:

1.一个声明在类里面的方法优先于任何默认方法(classes always win)

2.否则,则会优先选取最具体的实现,比如下面的例子 B重写了A的hello方法。

输出结果是:Hello World from B

如果想调用A的默认函数,则用到新语法X.super.m(...),下面修改C类,实现A接口,重写一个hello方法,如下所示:

public class C implements A{
    
    @Override
    public void hello(){
        A.super.hello();
    }
     
    public static void main(String[] args){
        new C().hello();
    }
}

输出结果是:Hello World from A

总结

默认方法给予我们修改接口而不破坏原来的实现类的结构提供了便利,目前java 8的集合框架已经大量使用了默认方法来改进了,当我们最终开始使用Java 8的lambdas表达式时,提供给我们一个平滑的过渡体验。也许将来我们会在API设计中看到更多的默认方法的应用。 

转载于:https://my.oschina.net/jewill/blog/413419

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值