为什么子类对象调用父类对象的方法,改变的居然是被子类隐藏掉的变量?
public class InheritTest
{
public static void main(String[] args)
{
B b = new B(3,4);
b.setValue(1, 2);
System.out.println(b.compute());//请问结果是什么?
}
}
class A {
int x;
int y;
public void setValue(int i,int j){
this.x = i;
this.y = j;
}
public int compute(){
return this.x*this.y;
}
}
class B extends A{
int x;
int y;
B(int i,int j){
this.x = i;
this.y = j;
}
public void setValue(int i,int j){
super.setValue(i, j);
}
public int compute(){
return this.x*this.y;
}
}
A的字节码:
// class version 49.0 (49)
// access flags 32
class org/zengge/test/A {
// compiled from: InheritTest.java
// access flags 0
I x
// access flags 0
I y
// access flags 0
<init>()V
L0 (0)
LINENUMBER 16 L0
ALOAD 0
INVOKESPECIAL java/lang/Object.<init>()V
RETURN
L1 (4)
LOCALVARIABLE this Lorg/zengge/test/A; L0 L1 0
MAXSTACK = 1
MAXLOCALS = 1
// access flags 1
public setValue(II)V
L0 (0)
LINENUMBER 20 L0
ALOAD 0
ILOAD 1
PUTFIELD org/zengge/test/A.x : I
L1 (4)
LINENUMBER 21 L1
ALOAD 0
ILOAD 2
PUTFIELD org/zengge/test/A.y : I
L2 (8)
LINENUMBER 22 L2
RETURN
L3 (10)
LOCALVARIABLE this Lorg/zengge/test/A; L0 L3 0
LOCALVARIABLE i I L0 L3 1
LOCALVARIABLE j I L0 L3 2
MAXSTACK = 2
MAXLOCALS = 3
// access flags 1
public compute()I
L0 (0)
LINENUMBER 25 L0
ALOAD 0
GETFIELD org/zengge/test/A.x : I
ALOAD 0
GETFIELD org/zengge/test/A.y : I
IMUL
IRETURN
L1 (7)
LOCALVARIABLE this Lorg/zengge/test/A; L0 L1 0
MAXSTACK = 2
MAXLOCALS = 1
}
可以看出setValue操作的是A对象的属性
而new B()的时候同时会产生一个A的对象,这时b相当于有4个属性,B.x,B.y,A.x,A.y只不过A.x与A.y被隐藏掉了,而调用setValue时,发变的实际上是A对象的x与y,所以最后打印出来的还是12,而不是2,B的属性值没有发生任何变化