考虑以下代码,它是LinkedList<E>
同时实现List<E>
和Deque<E>
的实际用例的提取。
可以观察到两个接口都有size()
和isEmpty()
方法,其中isEmpty()
方法可以默认为size()
。
所以,让我们这样做(使用虚拟接口),因为Java 8还没有这样做:
interface List<E> {
public int size();
default public boolean isEmpty() {
return (size() == 0);
}
//more list operations
}
interface Deque<E> {
public int size();
default public boolean isEmpty() {
return (size() == 0);
}
//more deque operations
}
class LinkedList<E> implements List<E>, Deque<E> {
private int size;
@Override
public int size() {
return size;
}
}
糟糕!我们在LinkedList
上收到编译时错误,因为它不知道要使用哪个isEmpty()
实现,所以我们添加:
@Override
public boolean isEmpty() {
return List.super.isEmpty();
}
现在我们已经失去了这个用例的默认方法的所有好处,因为它仍然需要我们编写isEmpty()
方法所需的代码。
但可以解决吗?是的!
考虑以下实施:
interface Sizable {
public int size();
default public boolean isEmpty() {
return (size() == 0);
}
}
interface List<E> extends Sizable {
//list operations
}
interface Deque<E> extends Sizable {
//deque operations
}
class LinkedList<E> implements List<E>, Deque<E> {
private int size;
@Override
public int size() {
return size;
}
}
所以问题:
答案 0 :(得分:4)
我强烈反对为定义default
方法添加不相关接口的超级接口。通常情况下,您没有这个问题,接口 与您的示例相关,因此像Collection
这样的自然超级接口存在或者可以定义为不仅仅是提供default
方法。或者它们实际上是无关的,并且实现两者的class
要么不太可能,要么必须定义要继承的语义。
如果Collection
API没有default
isEmpty
方法是有意的,因为size
对某些Collection
来说可能是一项昂贵的操作。如果您的Collection
分享了典型Collection
的行为,则可以继承AbstractCollection
。