[英]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()
隐式替换它,在这种情况下,它将转换为AbstractCollection
的contains()
被调用。 但是, 我在这里再次读到 , HashMap
/ HashSet
的containsAll()
的时间复杂度为O(n),这表明调用了HashSet
的contains()
(O(1))。 希望能清楚了解其背后的实际语义是什么。
不,这仅仅是多态。 每当在对象上调用方法时,该对象的真实类型就无关紧要。
含义:在Base中实现foo()
并不重要。 当foo()
调用bar()
, bar()
在Child中被覆盖。 当您有一个Child对象时,它将始终是被调用的Child bar()
版本。
在您的示例中, this
不是AbstractSet,而是HashSet
!
或换句话说:调用方法的“位置”无关紧要。 重要的是调用对象的类型。 如前所述,您的对象的类型为HashSet!
这是个有趣的问题。 Java中的HashSet
由HashMap
支持。 containsAll()
方法只是在contains()
循环,在这种情况下,是HashSet
的contains方法。 这是因为HashSet
覆盖了contains
和委托。
因为HashSet
由HashMap
支持,所以实际的调用是containsKey(Object key)
。
HashMap
的containsKey(Object key)
主要为您提供O(1)
复杂性。 但是, containsAll()
确实在n
元素上循环。 最坏情况下的复杂度变为O(n)
。
我之所以说这主要是因为HashMap
性能依赖于哈希。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.