使用"默认"的最佳方案是什么? java 8中的修饰符?

时间:2014-04-07 17:18:58

标签: java java-8

在新的Java 8规范语言中。他们引入了默认修饰符,允许在接口中定义方法。

我的问题是,有没有人知道这个功能的最佳用例是什么?

2 个答案:

答案 0 :(得分:6)

为避免破坏代码 - 支持API演变

典型的例子是它在Iterable接口中的使用,其中在Java 8中引入了default stream()方法。这样,所有Iterable都继承了已经被强制的stream方法自动的。这为API演变提供了支持,而不会破坏已有的代码。

定义合理的默认行为

假设您创建了一个新的Collection框架,定义它可能是合理的:

interface MyCollection {
    int size();
    default boolean isEmpty() { return size() == 0; }
}

通过这样做,您可以避免在所有实现类中以完全相同的方式重新定义isEmpty的痛苦,同时允许特定类在需要时以不同方式实现它。

这可以在抽象类中完成,但这使您可以删除层次结构中的一个层,并获得接口的继承灵活性:类可以继承多个接口,但只能继承一个抽象类。

另请参阅:Interface with default methods vs Abstract class in Java 8

答案 1 :(得分:1)

升级基本API

我认为他们推出此功能的主要原因是允许升级非常基本的界面 - CollectionIterableComparable, ...而不会导致与现有代码不兼容 - 如第一段中提到的 assylias

方法链接

此外,您可以通过method chaining获得非常有趣的结果 - 返回相同类型的方法以及他们调用的主链:

// Multiples of 5
final Predicate<Integer> fives = n -> n%5==0;
// Multiples of 7
final Predicate<Integer> sevens = n -> n%7==0;
// Multiples of 3
final Predicate<Integer> threes = n -> n%3==0;

// Multiples of 5 and 7 but not 3
final Predicate<Integer> compoundPredicate = fives.and(sevens).and(threes.negate());

由于广泛使用默认方法

,这是可能的
@FunctionalInterface 
public interface Predicate<T> {
    boolean test(T t);

    default Predicate<T> and(Predicate<? super T> other) {
        return (t) -> test(t) && other.test(t);
    }
    default Predicate<T> or(Predicate<? super T> other) {
        return (t) -> test(t) || other.test(t);
    }
    default Predicate<T> negate() {
        return (t) -> !test(t);
    } 
}

摆脱人工抽象类并为真正的继承腾出空间

对于默认行为,这不仅会删除一个完全人工层的抽象类(它纯粹是为默认行为而创建的),但它给出了您有机会介绍非常有用的抽象类,其中模拟实际 关系。

请参阅以下由游戏实施推动的示例。对于大多数(怪物,isDead()只是一个便利方法。但僵尸永远不会死,不是它。:)

enter image description here

enter image description here

enter image description here