繁体   English   中英

当超类型方法调用同时存在于超类型和子类型中的方法时,将调用哪个实例方法

[英]Which instance method is called when super type method calls method present in both super type and subtype

如果我在这里缺少一些核心Java,请原谅我。

我在HashSet的javadocs中搜索其Collection.containsAll()的实现规范,它显然继承了AbstractCollection的实现,根据JDK 8源代码文档 ,它是这样的:

public boolean containsAll(Collection<?> c) {
    for (Object e : c)
        if (!contains(e))
            return false;
    return true;
}

我的问题源于以下事实: HashSet不会覆盖containsAll() ,但是会覆盖contains()

public boolean contains(Object o) {
    return map.containsKey(o);
}

同样, AbstractCollection

public boolean contains(Object o) {
    Iterator<E> it = iterator();
    if (o==null) {
        while (it.hasNext())
            if (it.next()==null)
                return true;
    } else {
        while (it.hasNext())
            if (o.equals(it.next()))
                return true;
    }
    return false;
}

我的理解是,当未在实例中明确指定实例成员调用时,JVM会用this.instanceMemberCall()隐式替换它,在这种情况下,它将转换为AbstractCollectioncontains()被调用。 但是, 我在这里再次读到HashMap / HashSetcontainsAll()的时间复杂度为O(n),这表明调用了HashSetcontains() (O(1))。 希望能清楚了解其背后的实际语义是什么。

不,这仅仅是多态。 每当在对象上调用方法时,该对象的真实类型就无关紧要。

含义:在Base中实现foo()并不重要。 foo()调用bar()bar()在Child中被覆盖。 当您有一个Child对象时,它将始终是被调用的Child bar()版本。

在您的示例中, this不是AbstractSet,而是HashSet

或换句话说:调用方法的“位置”无关紧要。 重要的是调用对象的类型。 如前所述,您的对象的类型为HashSet!

这是个有趣的问题。 Java中的HashSetHashMap支持。 containsAll()方法只是在contains()循环,在这种情况下,是HashSet的contains方法。 这是因为HashSet覆盖了contains和委托。

因为HashSetHashMap支持,所以实际的调用是containsKey(Object key)

HashMapcontainsKey(Object key)主要为您提供O(1)复杂性。 但是, containsAll()确实在n元素上循环。 最坏情况下的复杂度变为O(n)

我之所以说这主要是因为HashMap性能依赖于哈希。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM