在新的Java 8规范语言中,它们引入了“default”修饰符,允许在接口中定义一个方法。
我的问题是,有没有人有这个特性的最佳使用案例的好主意?
我的问题是,有没有人有这个特性的最佳使用案例的好主意?
一个典型的例子是在Java 8中引入了Iterable
接口中的default stream()
方法。这样,所有的Iterable
都会自动继承一个已经实现的stream
方法。这为API演进提供了支持,而不会破坏已经存在的代码。
假设你创建了一个新的集合框架,定义一个合理的默认行为可能是很有必要的:
interface MyCollection {
int size();
default boolean isEmpty() { return size() == 0; }
}
isEmpty
所带来的痛苦,同时允许特定类在需要时以不同方式实现它。我认为引入此功能的主要原因是允许升级非常基本的接口-Collection
、Iterable
、Comparable
等,而不会对已存在的代码造成不兼容性,正如assylias在第一段中提到的。
此外,您可以通过方法链获得非常有趣的结果-这些方法返回相同的类型,并且您可以将它们链接起来调用:
// 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()
只是一种便利方法。但是,僵尸永远不会死,是吗? :)