[英]some questions about super() method in Java
In the book "Effective Java",I can't understand the result when I run the following code. 在“有效的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());
}
}
I can't understand why the result is six. 我不明白为什么结果是六。 I know that the addAll() method in parent class calls the add() method.
我知道父类中的addAll()方法调用add()方法。 But there is no 'count++' in add() method in parent class.
但是父类的add()方法中没有“ count ++”。 I initially thinK that subclass overrides the add() method,so the super().addAll() calls the add() method in subclass.
我最初是ThinK,该子类重写了add()方法,所以super()。addAll()调用了子类中的add()方法。 But when run the following code,I'm confused.
但是,当运行以下代码时,我很困惑。
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();
}
}
Why the result is 'this is parent'? 为什么结果是“这是父母”? According to the example in 'Effective Java', I think the result should be 'this is son'.
根据“有效Java”中的示例,我认为结果应该是“这是儿子”。 Please tell me what's wrong with me.
请告诉我我怎么了。
Below is java implementation of addAll() method. 下面是addAll()方法的Java实现。 As seen here, it calls add() internally.
如此处所示,它在内部调用add()。 So, you should increment your count in add() method alone.
因此,您应该单独在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;
}
So, when you call addAll() with a collection of 3 elements, count is increment immediately to 3 and then it increments by 1 each time your add() method is called. 因此,当您调用具有3个元素的集合的addAll()时,count会立即增加到3,然后每次调用add()方法时,count就会增加1。
I can't understand why the result is six.
我不明白为什么结果是六。
When you invoke super.addAll(c)
, you invoke the addAll()
method of the super class. 调用
super.addAll(c)
,将调用超类的addAll()
方法。
And addAll()
in HashSet
uses the implementation defined in AbstractCollection
that iterates on the collection in parameter and invokes add()
on each element : HashSet
addAll()
使用AbstractCollection
中定义的实现,该实现对参数中的集合进行迭代,并在每个元素上调用add()
:
public boolean addAll(Collection<? extends E> c) {
boolean modified = false;
for (E e : c)
if (add(e))
modified = true;
return modified;
}
So this code performs twice the incrementation : 因此,这段代码执行了两次递增:
@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
}
Here : 这里 :
count+= size; // + 3
and here : 和这里 :
return super.addAll(c); // + 3
The key point is polymorphism . 关键是多态性 。 Often, there are two versions of a method, with the same signature, but in two different classes, and both versions are accessible to code that's running.
通常,方法的两个版本具有相同的签名,但是在两个不同的类中,并且正在运行的代码都可以访问这两个版本。 The JVM has to decide which one to call, it bases its decision on the actual class of the object - not on the type of the variable that references the object, and not on which class it's currently running code from.
JVM必须决定要调用哪一个,它的决定是基于对象的实际类 -而不是引用对象的变量的类型,而不是当前运行代码的类。
In other words if x
is a variable that refers to an InstrumentHashSet
and you call x.add(something)
, it's the add
method in the InstrumentHashSet
class that gets called. 换句话说,如果
x
是引用InstrumentHashSet
的变量,并且您调用x.add(something)
,则将调用InstrumentHashSet
类中的add
方法。
In your example, when you call super.addAll
, this calls addAll
in the HashSet
class, which in turn calls add
once for each object that's being added. 在您的示例中,当您调用
super.addAll
,这将调用HashSet
类中的addAll
,后者依次为要添加的每个对象调用一次add
。 But because your object is an InstrumentHashSet
, it's the InstrumentHashSet
version of the add
method that gets called. 但是因为您的对象是
InstrumentHashSet
,所以它是被调用的add
方法的InstrumentHashSet
版本。
So your code runs count += size;
因此,您的代码运行
count += size;
(which sets count
to 3) then makes three calls to your add
method, each of which increments count
. (将
count
设置为3)然后对add
方法进行三个调用,每个调用都会递增count
。 The end result is that count
is 6. 最终结果是
count
为6。
I initially thinK that subclass overrides the add() method,so the super().addAll() calls the add() method in subclass. 我最初是ThinK,该子类重写了add()方法,所以super()。addAll()调用了子类中的add()方法。 But when run the following code,I'm confused.
但是,当运行以下代码时,我很困惑。
-- You are Correct - 你是对的
When it will override and print "this is son", below code will print "this is son" 当它覆盖并打印“ this is son”时,下面的代码将打印“ this is son”
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.