default关键字详解

4 篇文章 0 订阅
2 篇文章 0 订阅

在JDK 1.8之前,default关键字用来标记switch语句中的默认分支。表示当不匹配任何case的时候,就会执行default代码块。

    String ss = "123456789";
    switch (ss) {
        case "123":
            break;
        case "456":
            break;
        case "789":
            break;
        default:
            System.out.println("123456789");
    }

JDK 1.8 引入很多新的特性,其中有lambda表达式,default方法,新的Date API等。在1.8之前,要在接口中引入新的方法,就必须打破现有的实现。而且 1.8 新引入的Lambda表达式,有明显的局限性,他们不能被重写的类实现扩展的接口,所有就有了default方法(Virtual extension methods)。

Default方法是指,在接口内部包含了一些默认的方法实现(也就是接口中可以包含方法体,这打破了Java之前版本对接口的语法限制),从而使得接口在进行扩展的时候,不会破坏与接口相关的实现类代码,例如:

public interface A {

    void method2();

    default void method1(){
        System.out.println("run method1");
    }
}

class impl implements A{

    @Override
    public void method2() {
        System.out.println("run method2");
    }

    public static void main(String[] args) {
        new impl().method1();
        new impl().method2();
    }
}

在这里,default方法,在接口中必须要有方法体,不然就会报错。



上面是简单的default方法使用,让我们来看看下面几种情况,更详细的理清default方法的使用。

1、

interface A {
    default void m() {
        System.out.println("123");
    }
}

interface B extends A {

}

interface C extends A {

}

class D implements B, C {

}

在这个例子中,尽管D继承m()从B和C,当我们构建接口提供了一个默认的m()方法中,我们看到的只有一个m() D实现了A中的m()。

interface A {
    default void m() {
        System.out.println("123");
    }
}

interface B extends A {
    default void m() {
        System.out.println("1234");
    }
}

interface C extends A {
    default void m() {
        System.out.println("12345");
    }
}

class D implements B, C {

}

在这种情况下,D中m()继承会暧昧(因为最具体的设置默认提供接口包含B和C)。在编译时D会被拒绝,除非D实现了m()。

2、

在下面的例子中,m()在D中必须实现abstract 方法,因为在C中的抽象声明优先于默认,不然也会报错。

interface A {
    default void m() {
        System.out.println("123");
    }
}

abstract class C {
    abstract void m();
}

class D extends C implements A {

}

3、

B的声明没有移除a的默认值 , B是相同的没声明m()。

interface A {
    default void m() {
        System.out.println("123");
    }
}

interface B extends A {
    void m();
}

4

当C同时实现了A,B 且A,B有不同的default 方法,方法名相同时,使用通过A.super.m() 来实现,不然编译的时候会产生错误,因为编译期不知道选择哪一个。

interface A {
    default void m() {
        System.out.println("123");
    }
}

interface B {
    default void m() {
        System.out.println("456");
    }
}

class C implements A, B {
    public void m() {
        A.super.m();
    }
}

class D implements A {
    public void m() {
        System.out.println("Calling m");
        A.super.m();
    }
}

上面是一些关于default使用中需要注意的一些,还有其他一些注意的,没有一一罗列,因为博主也是慢慢学习过程。如果有错误,也请大家不要吝啬,指点一二。

参考文献: Interface evolution via virtual extension methods

  • 7
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值