关闭

Java 8 Default Methods

标签: javajdk
125人阅读 评论(0) 收藏 举报
分类:

如果翻看jdk源码的interface,会发现多了default关键词。
简单介绍下。
原文

default使我们能够在不中断实现该接口的类的情况下向接口添加新的功能。 让我们来看看下面的例子。

public class MyClass implements InterfaceA {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
    }

    @Override
    public void saySomething() {
        System.out.println("Hello World");
    }

}

interface InterfaceA {
  public void saySomething(); 

}

上面的代码显示了类MyClass实现InterfaceA的方法saySomething()。 现在我们给InterfaceA添加一个名为sayHi()的新方法。 通过这样做,我们向类MyClass引入一个问题,因为它不会编译,直到我们提供方法sayHi()的实现。
这时Default就有用了。 通过在方法的访问修饰符之前添加关键字default,我们不必为类MyClass中的方法sayHi()提供实现。
在最严格的意义上,default是倒退一步,因为它们允许你用代码“污染”你的接口。 但它们提供了最优雅和实用的方式来允许向后兼容性。 它使jdk更容易更新所有Collections类,并为您改装现有的Lambda代码。(其实这就是default产生最初原因)

public class MyClass implements InterfaceA {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
    }

    @Override
    public void saySomething() {
        System.out.println("Hello World");
    }

}

interface InterfaceA {

    public void saySomething();

    default public void sayHi() {
      System.out.println("Hi");
    }

}

注意,我们必须提供所有default方法的实现。 因此,default方法为我们提供了在接口中实现方法的灵活性。 如果具体类不提供该方法的实现,那么实现将被用作默认值。

多接口冲突

由于java中的类可以实现多个接口,可能会有一个情况,其中两个或更多的接口有一个default方法具有相同的名称,因此导致冲突,因为java不知道一次使用什么方法。 这将导致编译错误:类MyClass从类型InterfaceA和InterfaceB继承default sayHi()
让我们来看看下面的例子。

public class MyClass implements InterfaceA, InterfaceB {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
    }

    @Override
    public void saySomething() {
        System.out.println("Hello World");
    }

}

interface InterfaceA {

    public void saySomething();

    default public void sayHi() {
        System.out.println("Hi from InterfaceA");
    }

}

interface InterfaceB {
     default public void sayHi() {
        System.out.println("Hi from InterfaceB");
    }
}

为了解决这样的情况,我们必须在类MyClass中提供sayHi()方法的实现,因此覆盖InterfaceA和InterfaceB中的两个方法。

public class MyClass implements InterfaceA, InterfaceB {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
    }

    @Override
    public void saySomething() {
        System.out.println("Hello World");
    }

    @Override
    public void sayHi() {
        System.out.println("implemetation of sayHi() in MyClass");
    }

}

interface InterfaceA {

    public void saySomething();

    default public void sayHi() {
        System.out.println("Hi from InterfaceA");
    }

}

interface InterfaceB {
     default public void sayHi() {
        System.out.println("Hi from InterfaceB");
    }
}

如果我们想要在InterfaceA或InterfaceB中专门调用一个sayHi()方法,我们也可以这样做:

public class MyClass implements InterfaceA, InterfaceB {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
    }

    @Override
    public void saySomething() {
        System.out.println("Hello World");
    }

    @Override
    public void sayHi() {
       InterfaceA.super.sayHi();
    }

}

interface InterfaceA {

    public void saySomething();

    default public void sayHi() {
        System.out.println("Hi from InterfaceA");
    }

}

interface InterfaceB {
     default public void sayHi() {
        System.out.println("Hi from InterfaceB");
    }
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:21293次
    • 积分:523
    • 等级:
    • 排名:千里之外
    • 原创:23篇
    • 转载:0篇
    • 译文:9篇
    • 评论:0条
    文章分类