为什么super.addAll会调用重写的add方法

时间:2013-05-10 06:50:59

标签: java

我有一个myHashSet类,它扩展了HashSet类。 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 个答案:

答案 0 :(得分:4)

这是多态性的工作方式。

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

答案 1 :(得分:3)

您已覆盖add()。这意味着只要在add()的实例上调用MyHashSet,就会调用重写的方法。呼叫站点的位置并不重要:即使它在超类型的方法中,也会调用被覆盖的方法。你为什么期望它能起作用呢?

答案 2 :(得分:1)

呼叫顺序如下:

  1. 您致电MyHashSet::addAll()
  2. MyHashSet::addAll()使用HashSet::addAll()
  3. 致电super->addAll()
  4. HashSet::addAll()使用MyHashSet::add()
  5. 致电this->add()
  6. MyHashSet::add()使用HashSet::add()
  7. 致电super->add()

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

答案 3 :(得分:0)

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