美文网首页编程it互联网
Java8 -Default Methods

Java8 -Default Methods

作者: 咪啊p | 来源:发表于2019-10-31 13:18 被阅读0次

为什么Java 8推出了default methods?

  1. 在Java1.7的版本里面,接口只允许存在public abstract 方法,或者public static final 变量,不管你是否声明,interface里面的定义的方法,隐含一定是public abstract的
  2. 同样,每个声明在interface里面的变量,隐含也一定是public static final的,无论你是否明确声明
  3. 在Java 8的时候,我们可以在interface里面定义一个确切的方法,而不是抽象方法,这个方法需要加上default关键字,称之为default method,比如
default void method1(){
    System.out.println("default method1");
}
  1. 所有实现此接口的类都将继承这个default方法,可以直接使用,也可以覆盖

由上,我们大概可以猜出default method的作用:主要是为了方便向后兼容,扩展已有接口,但是不影响其他的实现类;如果没有默认方法,给某个接口添加一个新的抽象方法,那么所有实现了该接口的类都得修改,影响将会非常大

Default method

  1. 默认方法的语法很简单就是在interface里面定义一个带有default关键字的方法,就是default method
  2. default method默认就是可以被所有它的实现类使用,当然如果需要,类里面也可以覆盖这个default method。下面看个简单的例子:
Interface inter {
    default void method1(){
        System.out.println("default method1");
    }
}
Class Demo implements Interf {
    public static void main(String[] args) {
        Demo demo = new Demo ();
        demo.method1();
   }
}
  1. 一个接口继承另外一个接口,同样会继承接口里面的default methods
  2. 如果两个接口定义同样名字的default method,这个时候一个类同时实现了这两个接口会这么样呢?
Interface interf1{
   default void method1(){
        System.out.println("default method1 from Interf1");
    }
}

Interface interf2{
   default void method1(){
        System.out.println("default method1 from Interf2");
    }
}
class Demo implements interf1, interf2{ // compile error
}

上面的代码,Demo类会报编译错误,要求你去覆盖method1 方法,因为编译器不知道哪个method1方法是你需要的。我们修改下Demo类

Class Demo implements Interf1, interf2 {
@Override
    public void method1() {
        System.out.println("method1 from Demo");// Or Interf1.super.method1();
    }

    public static void main(String[] args) {
        Demo demo = new Demo ();
        demo.method1();
   }
}

interface with default methods 不同于 abstract class

即使interface里面可以定义确切的方法,但是还是并不等同于抽象类

带有默认方法的接口 抽象类
接口里面定义的变量永远是public static final的,不能定义instance变量 抽象类里面是允许出现instance变量的
Interface never talks about state of Object. Abstract class can talk about state of Object.
Interface里面不能定义构造方法 抽象类里面可以
不能定义static,instance block 抽象类里面可以
Default method can refer lambda expression 抽象类里不可以
不能override Object 方法 抽象类里可以

Java Comparator

比如Java8 里面Comparator接口,通常我们需要sort的时候需要实现Comparator接口, 因为Comparator是一个functional interface,我们可以使用lambda表达式

myDeck.sort(
    (firstCard, secondCard) ->
        firstCard.getRank().value() - secondCard.getRank().value()
);

Comparator实现一个[Comparing]方法,将会更加方便,如下:

myDeck.sort(Comparator.comparing(Card::getRank));  

Comparator 接口还提供了其他的一些方法比如 comparingDoublecomparingLong .

假设你想比较对一个cards排序,首先根据它的rank,然后根据他的suit,那么你可能会写成如下的代码:

StandardDeck myDeck = new StandardDeck();
myDeck.shuffle();
myDeck.sort(
    (firstCard, secondCard) -> {
        int compare =
            firstCard.getRank().value() - secondCard.getRank().value();
        if (compare != 0)
            return compare;
        else
            return firstCard.getSuit().value() - secondCard.getSuit().value();
    }      
); 

Comparator接口提供了更加方便的方法 thenComparing:

myDeck.sort(
    Comparator
        .comparing(Card::getRank)
        .thenComparing(Comparator.comparing(Card::getSuit)));

由这个例子我们可以看到,Comparator 接口是如何通过default method来增强它的功能。

参考资料

https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html

相关文章

网友评论

    本文标题:Java8 -Default Methods

    本文链接:https://www.haomeiwen.com/subject/bfcavctx.html