在本书#34; Effective Java"中,当我运行以下代码时,我无法理解结果。
public class InstrumentHashSet<E> extends HashSet<E>{
private int count;
@Override
public boolean add(E e) {
// TODO Auto-generated method stub
count++;
return super.add(e);
}
@Override
public boolean addAll(Collection<? extends E> c) {
// TODO Auto-generated method stub
int size = c.size();
count+= size;
return super.addAll(c);
}
public int getCount(){
return count;
}
public static void main(String[] args) {
InstrumentHashSet<String> s = new InstrumentHashSet<String>();
s.addAll(Arrays.asList("xinwa1","xinwa2","xinwa3"));
System.out.println("hashSet count:"+s.getCount());
}
}
我无法理解为什么结果是六。我知道父类中的addAll()方法调用add()方法。但是没有“计数++”。在父类的add()方法中。我最初瘦的那个子类重写了add()方法,所以super()。addAll()调用子类中的add()方法。但是当运行以下代码时,我很困惑。
class Point {
public int x;
public int y;
public Point(int x,int y) {
this.x= x;
this.y= y;
}
public void method() {
System.out.println("this is parent");
}
}
public class ColorPoint extends Point{
public ColorPoint(int x, int y) {
super(x, y);
}
@Override
public void method() {
System.out.println("this is son");
}
public void print() {
super.method();
}
public static void main(String[] args) {
ColorPoint c = new ColorPoint(1, 2);
c.print();
}
}
为什么结果是&#39;这是父母&#39;?根据“有效Java”中的例子,我认为结果应该是“这是儿子”。请告诉我我的错误。
答案 0 :(得分:0)
下面是addAll()方法的java实现。如此处所示,它在内部调用add()。因此,您应该仅在add()方法中增加计数。
public boolean More ...addAll(Collection<? extends E> c) {
boolean modified = false;
Iterator<? extends E> e = c.iterator();
while (e.hasNext()) {
if (add(e.next()))
modified = true;
}
return modified;
}
因此,当您使用3个元素的集合调用addAll()时,count会立即递增到3,然后每次调用add()方法时递增1。
答案 1 :(得分:0)
我无法理解为什么结果是六。
当您调用super.addAll(c)
时,您将调用超类的addAll()
方法。
addAll()
中的HashSet
使用AbstractCollection
中定义的实现,该实现迭代参数中的集合并在每个元素上调用add()
:
public boolean addAll(Collection<? extends E> c) {
boolean modified = false;
for (E e : c)
if (add(e))
modified = true;
return modified;
}
因此,此代码执行两次增量:
@Override
public boolean addAll(Collection<? extends E> c) {
// TODO Auto-generated method stub
int size = c.size();
count+= size; // + 3
return super.addAll(c); // + 3
}
这里:
count+= size; // + 3
在这里:
return super.addAll(c); // + 3
答案 2 :(得分:0)
关键点是多态。通常,有两个版本的方法,具有相同的签名,但是在两个不同的类中,并且两个版本都可以运行的代码访问。 JVM必须决定调用哪一个,它的决定权基于对象的实际类 - 而不是引用该对象的变量的类型,而不是它所在的类#& s当前正在运行代码。
换句话说,如果x
是引用InstrumentHashSet
的变量并且您调用x.add(something)
,则它是add
中的InstrumentHashSet
方法被调用的类。
在您的示例中,当您致电super.addAll
时,会调用addAll
类中的HashSet
,而add
类会针对每个对象调用InstrumentHashSet
一次被添加。但由于您的对象是InstrumentHashSet
,因此调用add
方法的count += size;
版本。
因此,您的代码会运行count
(将add
设置为3)然后对您的count
方法进行三次调用,每次调用都会增加count
。最终结果是tiles = [
{text: 'One', cols: 1, rows: 2, color: 'lightblue'}
];
为6。
答案 3 :(得分:0)
我最初瘦瘦的那个子类重写了add()方法,所以super()。addAll()调用子类中的add()方法。但是当运行以下代码时,我很困惑。
- 你是正确的
当它覆盖并打印“这是儿子”时,下面的代码将打印“这是儿子”
class Point {
public int x;
public int y;
public Point(int x,int y) {
this.x= x;
this.y= y;
}
public void method() {
System.out.println("this is parent");
}
}
public void print() {
method();
}
public class ColorPoint extends Point{
public ColorPoint(int x, int y) {
super(x, y);
}
@Override
public void method() {
System.out.println("this is son");
}
public static void main(String[] args) {
ColorPoint c = new ColorPoint(1, 2);
c.print();
}
}
You are using object which is instance of ColorPoint, all methods
will be called from ColorPoint class implemenation, if any method is
not present it will call parents method.
When you call print on ColorPoint, it is not present in ColorPoint,
so call print() in method(but you are still using ColorPoint
instance).
Now print calls method, it is present in ColorPoint, so call method
in ColorPoint and not parent.
Whenever you call method like super.method() then it will always try
to call method from super