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

ski*_*iwi 5 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

糟糕!我们在上遇到了编译时错误LinkedList,因为它不知道isEmpty()要使用哪种实现,因此我们添加了以下内容:

@Override
public boolean isEmpty() {
    return List.super.isEmpty();
}
Run Code Online (Sandbox Code Playgroud)

现在,对于该用例,我们几乎已经失去了默认方法的所有好处,因为编写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;
    }
}
Run Code Online (Sandbox Code Playgroud)

所以问题是

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

Hol*_*ger 4

我强烈反对仅仅为了定义方法而为不相关的接口添加超级接口default。通常,您不会遇到这个问题,因为接口像您的示例中那样相关,因此存在像这样的自然超级接口Collection,或者可以定义它而不仅仅是提供default方法。或者它们确实不相关并且class实现两者要么不太可能,要么必须定义要继承的语义。

\n\n

如果CollectionAPI 没有default方法isEmpty是故意的,因为size对于某些 s 来说这可能是一项昂贵的操作Collection。如果你的Collection行为与典型的Collections 相同,你可能会继承AbstractCollection

\n