public class Test1 {
public int a ;
public Test1(){
a=3;
}
public void addFive(){
a+=5;
}
public static void main(String[] args) {
Test1 t = new Test2();
t.addFive();
System.out.println(t.a);
}
}
class Test2 extends Test1{
public int a;
public Test2(){
a=8;
}
public void addFive(){
a+=5;
}
}为什么结果是3呢?这个对象的堆空间是怎么搞的?
public int a ;
public Test1(){
a=3;
}
public void addFive(){
a+=5;
}
public static void main(String[] args) {
Test1 t = new Test2();
t.addFive();
System.out.println(t.a);
}
}
class Test2 extends Test1{
public int a;
public Test2(){
a=8;
}
public void addFive(){
a+=5;
}
}为什么结果是3呢?这个对象的堆空间是怎么搞的?
{
Test1 t = new Test2();
t.addFive();
System.out.println(t.getA());
}
public int getA()
{
return a;
}public static void main(String[] args)
{
Test2 t = new Test2();
t.addFive();
System.out.println(t.a);
}楼主试试换成这两种看看
属性只有隐藏之说 没有重写的概念,用什么类型引用掉就访问哪个的
而方法则有重写,调用实际对象的方法
|-----------|
| 父类内存 |
| 父类的a |
|-----------|
| 子类内存 |
| 子类的a |
|-----------|
| VT |
|-----------|VT是方法管理的虚拟表(viture table)
可以想象成这样一个内存模型,子类对象是个大整体,父类对象是子类对象的一部分
this包含整个大整体的空间,super包含父类对象的内存空间
当你用父类引用变量指向子类对象的时候,引用有效部分只是父类内存空间和VT,即子类扩展的新的属性和方法,父类引用变量是访问不到的
LZ可以试试在Test2追加一个新的方法,如addSix();
然后调用 t.addSix()看看,就知道t能访问的范围了
如果此时想访问 addSix(),必须转换为子类对象才可以,即
((Test2)t).addSix()
(Test2)t实际上就是相当于一个临时变量 Test2 t2 = (Test2)t;
LZ再好好体会一下这其中的意思吧