我有一个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()?
我在这里很困惑,如果这个问题非常愚蠢,那就很抱歉。
答案 0 :(得分:4)
这是多态性的工作方式。
如果您有类层次结构A和B,其中B扩展A并且在调用它时已经重写了方法foo()
,则将执行子类的方法。语法super.foo()
允许调用超类的方法版本。但是如果那时超类的方法调用bar()
,它将调用在子类中编写的版本。想一想:这允许继承工作,因为您可以覆盖子类中的超类方法并更改功能。
答案 1 :(得分:3)
您已覆盖add()
。这意味着只要在add()
的实例上调用MyHashSet
,就会调用重写的方法。呼叫站点的位置并不重要:即使它在超类型的方法中,也会调用被覆盖的方法。你为什么期望它能起作用呢?
答案 2 :(得分:1)
呼叫顺序如下:
MyHashSet::addAll()
MyHashSet::addAll()
使用HashSet::addAll()
super->addAll()
HashSet::addAll()
使用MyHashSet::add()
this->add()
MyHashSet::add()
使用HashSet::add()
super->add()
醇>
在步骤1和3中,调用是virtual
,因此他们调用最新的实现。
答案 3 :(得分:0)
MyHashSet's addAll()
里面使用了MyHashSet's add()
方法。你覆盖了那个方法所以很明显它会来到那里。