当前位置: 代码迷 >> Java面试 >> java里面关于继承的一道面试题
  详细解决方案

java里面关于继承的一道面试题

热度:660   发布时间:2014-02-25 23:05:31.0

求大神解释,为什么test调用父类i,却调用子类的方法

Java代码
  1. public class T1 {  

  2.  

  3.    int i = 0;  

  4.  

  5.    public void Test1() {  

  6.        System.out.println(i);  

  7.    }  

  8.  

  9.    public void Test2() {  

  10.        System.out.println(i);  

  11.    }  

  12. }  

  13.  

  14.  

  15. public class T2 extends T1 {  

  16.  

  17.    int i = 2;  

  18.  

  19.    public void Test2() {  

  20.        System.out.println(i);  

  21.    }  

  22.  

  23.    public static void main(String[] args) {  

  24.        T1 test = new T2();  

  25.        test.Test1();  

  26.        test.Test2();  

  27.        System.out.println(test.i);  

  28.        test = (T2)test;  

  29.        System.out.println(test.i);  

  30.          

  31.    }  

  32. }  

==============解决方案=====================

这是java的重写,子类重写了父类的方法。

另外,你new的是子类,只是用了一个父类接口去引用,他本质还是子类的对象。所以你调用test2永远都是调用子类的。这点和c++不一样

===============解决方案=====================

test的引用类型是T1,实质是T2的实例
第一个输出test.Test1()运行的是T2实例的方法
T2实例的初始化过程是从根父类开始的,可以大致理解为栈状结构逐层构建
T2方法
T2域
T1方法
T1域
T0方法
T0域
test作为T2实例继承T1的Test1()方法实际并没有复制,运行Test1()时其实质是在栈中向下搜索至T1的Test1()方法,该方法中的println向下寻找i,于是结果是T1中的i。如果T1有父类T0也有一个域i,也会被覆盖。

第二个输出test.Test2()也可以作类似理解。其实T1作为引用类型只是限制了test可用“哪一些”方法,不可以调用子类独有父类没有的方法,仅此而已,至于运行“哪一个”(继承过程中的)方法就是由T2实例决定的,所以只要子类有的方法不会去找父类,没有的话就向下找。

上面关于方法的调用是由实例决定的,是多态的特性,同一个父类引用装入不同实例就有不同方法,但变量不一样,变量只是方法的辅助对象的属性,变量和多态没有直接关系不会受实例类型影响,获取的变量值和引用类型有关,所以第三个输出T1引用类型的test的i是0。

至于第四个输出前强制转型test = (T2)test;后test依然是T1引用类型并没有改变,所以输出依然是T1的i值0。如果句子是T2 test2 = (T2)test;输出test2的i值将会是2。

===================解决方案============================

T1和T2中都有i,这其实代表不同地址中的数据
为了便于理解,其实应该把T2中的i改成i2
T1 test = new T2();
这创建的是一个T1对象
无论是否强转,test.i都是最初创建时的值。所以System.out.println(test.i);  结果都是0
Test1() 打印结果肯定为0.
Test2() 被子类重写,打印的结果为1.

  相关解决方案