5

考虑下面的代码,它是一个实际用例的提取,其中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 在未来实现中应该如何处理它的方式吗?
4

1 回答 1

4

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

如果CollectionAPI 没有default方法 forisEmpty是故意的,因为对于某些ssize来说可能是昂贵的操作。Collection如果您Collection与典型Collection的 s 共享行为,您可能会继承自AbstractCollection.

于 2014-04-08T09:04:57.527 回答