java - 当超类型方法调用超类型和子类型中都存在的方法时调用哪个实例方法
问题描述
如果我在这里遗漏了一些核心 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
/的时间复杂度将是 O(n),这表明's HashSet
( O(1)) 被调用。希望能清楚地了解这背后的实际语义是什么。containsAll()
HashSet
contains()
解决方案
不,这只是多态性。每当在对象上调用方法时,该对象的真实类型很重要,仅此而已。
foo()
含义:在 Base 中实现并不重要。当在 Child 中被覆盖时foo()
调用。当你有一个 Child 对象时,它总是会被调用的 Child 版本。bar()
bar()
bar()
在您的示例中,this
不是 AbstractSet,它是HashSet
!
或者换句话说:调用方法的“位置”并不重要。重要的是调用它的对象的类型。如前所述,您的对象是 HashSet 类型!
推荐阅读
- token - 如何将访问令牌设置为在几秒钟内过期
- python - 使用 BeautifulSoup 抓取玩家数据
- python - Profile() 有一个意外的关键字参数“用户”
- node.js - NodeJS 和猫鼬 CastError: Cast to [ObjectId] failed for value
- javascript - 何时将作为参数分配的值传递给 setState 函数?
- python - 在过滤和分组后显示所有起始的不同元素
- x86 - 为什么在 db 指令之后没有执行任何代码?
- git - Git to Mercurial 转换提交消息参考
- git - 如何将 git 远程分支名称从大写重命名为小写相同名称?
- javafx - 频繁的音频占用过多的 CPU - JavaFX