gpt4 book ai didi

java - 创建扩展哈希集/继承的计数类

转载 作者:行者123 更新时间:2023-11-29 07:08:49 25 4
gpt4 key购买 nike

如果我们考虑以下类来计算添加到 HashSet 中的对象:

public class CountingHashSet<E> extends HashSet<E> {

public int addCount = 0;

@Override
public boolean add(E e) {
addCount +=1;
return super.add(e);
}

@Override
public boolean addAll(Collection<?
extends E> c) {
addCount += c.size();
return super.addAll(c);
}

然后,JUnit 测试失败了:

@Test
public void testCount() {
CountingHashSet<Integer> s = new CountingHashSet<>();
s.addAll(Arrays.asList(1, 2, 3, 4, 5));
for (int i = 6; i <= 10; ++i)
s.add(i);
assertEquals(10, s.addCount);
}

我得到以下信息:

java.lang.AssertionError: expected:<10> but was <15>

为什么我得到 15?在我看来,s.addAll(myCollection) 调用 super.addAll(c),如果我查看 hashSet 的源代码,我看到addAll(c) 调用 add(e) 来添加每个元素。但是为什么super.addAll(c)调用我重新定义的add方法呢? (这就是为什么我得到 15 而不是 10)

最佳答案

您将继承视为组合。它不是。调用最终不是“HashSet 上的add()”——它们最终是“当前对象上的add()” ".

But why super.addAll(c) call the add method that I redefined ?

因为这就是虚拟方法的行为方式。 addAll 只是调用 add(),它将使用实际类型中最重写的实现。这就是多态性总是 的工作原理。让我们写一个更简单的例子:

class Superclass {
public void foo() {
bar();
}

public void bar() {
System.out.println("Superclass.bar()");
}
}

class Subclass extends Superclass {
@Override
public void bar() {
System.out.println("Subclass.bar()");
}
}

public class Test {

public static void main(String [] args) {
Superclass x = new Subclass();
x.foo(); // Prints Subclass.bar()
}
}

Subclass.bar() 的结果是您期望从此示例中得到的结果吗?如果是这样,您认为您的版本会有什么不同?仅仅因为您正在调用 super.addAll() 并不意味着该对象突然处于“非覆盖”模式或类似模式。

关于java - 创建扩展哈希集/继承的计数类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16426752/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com