子接口是否是默认方法冲突的解决方案?

时间:2014-04-07 19:24:42

标签: java inheritance java-8 default-method

考虑以下代码,它是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;
    }
}

所以问题

  • 这是我们以及JDK应该如何在未来的实现中处理它吗?

1 个答案:

答案 0 :(得分:4)

我强烈反对为定义default方法添加不相关接口的超级接口。通常情况下,您没有这个问题,接口 与您的示例相关,因此像Collection这样的自然超级接口存在或者可以定义为不仅仅是提供default方法。或者它们实际上是无关的,并且实现两者的class要么不太可能,要么必须定义要继承的语义。

如果Collection API没有default isEmpty方法是有意的,因为size对某些Collection来说可能是一项昂贵的操作。如果您的Collection分享了典型Collection的行为,则可以继承AbstractCollection