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

Java 为什么super.addAll调用重写的add方法,java,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(Collec

我有一个类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呢


我在这里感到困惑,如果这个问题很愚蠢,我很抱歉。

这就是多态性的工作方式


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

这就是多态性的工作方式


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

您已覆盖add。这意味着每当对MyHashSet的实例调用add时,就会调用重写的方法。调用站点位于何处并不重要:即使它位于超级类型的方法中,也会调用被重写的方法。为什么您希望它以其他方式工作?

您已经覆盖了add。这意味着每当对MyHashSet的实例调用add时,就会调用重写的方法。调用站点位于何处并不重要:即使它位于超级类型的方法中,也会调用被重写的方法。为什么您希望它以其他方式工作?

调用顺序如下:

您可以调用MyHashSet::addAll MyHashSet::addAll使用super->addAll调用HashSet::addAll HashSet::addAll使用此->add调用MyHashSet::add MyHashSet::add使用super->add调用HashSet::add
在步骤1和步骤3中,调用是虚拟的,因此它们调用最新的实现。

调用顺序如下:

您可以调用MyHashSet::addAll MyHashSet::addAll使用super->addAll调用HashSet::addAll HashSet::addAll使用此->add调用MyHashSet::add MyHashSet::add使用super->add调用HashSet::add
在步骤1和3中,调用是虚拟的,因此,他们调用了最新的实现。

MyHashSet的addAll在内部使用了MyHashSet的add方法。您覆盖了该方法,因此它显然会出现。

MyHashSet的addAll在内部使用了MyHashSet的add方法。您覆盖了该方法,因此它显然会出现。

这不是它的工作方式。因为add是在这个函数上调用的,而这是一个MyHashSet,所以会调用该方法的最具体版本。@devdekku但我使用super.addAll和super.add,它们必须调用super类的方法,对吗?这里没有这个。你使用super.addAll,super.addAll使用this.add,它依次委托给super.add,这样你就可以删除它。它不是这样工作的。因为add是在这个函数上调用的,而这是一个MyHashSet,所以会调用该方法的最具体版本。@devdekku但我使用super.addAll和super.add,它们必须调用super类的方法,对吗?这里没有这个。你使用Suff.AdALL和Suff.Addiar使用这个。添加,它反过来代表Suff.Advices,所以你也可以删除它。我认为虚拟是一个C++概念,这里提到它可能会混淆java初学者。我认为虚拟是C++概念,这里提到它可能会混淆java初学者。