在新的Java 8规范语言中。他们引入了默认修饰符,允许在接口中定义方法。
我的问题是,有没有人知道这个功能的最佳用例是什么?
答案 0 :(得分:6)
典型的例子是它在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)
我认为他们推出此功能的主要原因是允许升级非常基本的界面 - Collection
,Iterable
,Comparable
, ...而不会导致与现有代码不兼容 - 如第一段中提到的 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()
只是一个便利方法。但僵尸永远不会死,不是它。:)