1

我有一个扩展 HashSet 类的 myHashSet 类。myHashSet 覆盖 HashSet 的 add() 和 addAll() 方法。所以我有以下代码片段:

class MyHashSet<E> extends HashSet<E> {

    @Override
    public boolean add(E e){
       return super.add(e);
    }

    @Override
    public boolean addAll(Collection ? extends E> c){
       return super.addAll(c);
    }
}

我知道,addAll 方法是通过 add() 实现的,这意味着它使用 add() 方法。所以,如果我调用 MyHashSet 的 addAll(),它应该调用 HashSet 的 addAll(),而后者又应该调用 HashSet 的 add()。但是为什么当我调用 MyHashSet 的 addAll() 时它调用 MyHashSet 的 add()?

我在这里很困惑,对不起,如果这个问题很愚蠢。

4

4 回答 4

4

这就是多态性的工作方式。

如果您有类层次结构 A 和 B 其中 B 扩展 A 并且您foo()在调用它时覆盖了方法,则将执行子类的方法。该语法super.foo() 允许调用超类的方法版本。但是如果然后超类的方法调用bar()它将调用子类中编写的版本。想一想:这允许继承工作,因为您可以覆盖 sublass 中超类的方法并更改功能。

于 2013-05-10T06:56:48.297 回答
3

你已经覆盖了add(). 这意味着每当add()在 的实例上调用时MyHashSet,都会调用您的覆盖方法。调用站点在哪里并不重要:即使它在超类型的方法中,您的覆盖方法也会被调用。为什么你会期望它以其他方式工作?

于 2013-05-10T06:57:06.487 回答
1

调用顺序如下:

  1. 你打电话MyHashSet::addAll()
  2. MyHashSet::addAll()调用HashSet::addAll()使用super->addAll()
  3. HashSet::addAll()调用MyHashSet::add()使用this->add()
  4. MyHashSet::add()调用HashSet::add()使用super->add()

在第 1 步和第 3 步中,调用是virtual,因此它们调用最新的实现。

于 2013-05-10T06:59:33.700 回答
0

MyHashSet's addAll()在里面使用MyHashSet's add()了方法。你覆盖了那个方法所以很明显它会出现在那里。

于 2013-05-10T06:59:58.350 回答