浏览 1255 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2012-05-20
最后修改:2012-05-20
package com.yjk; public class Parent { //定义一个名为i的实例变量 private int i = 1; public Parent() { this.display(); } public void display() { System.out.println(i); } } --------------------------------------------------------------------- public class Son extends Parent { //定义一个名为i的实例变量 private int i = 2; //构造器,将实例变量i初始化为3 public Son() { i = 3; //⑵ } public void display() { System.out.println(i); } } --------------------------------------------------------------------- package com.yjk; public class Test { public static void main(String[] args) { //创建子类实例 new Son(); //⑴ } } } --------------------------------------------------------------------- 这行代码会调用子类Son里的构造器,由于子类Son继承了父类Parent,而且子类Son的构造器中,并没有显示的使用Super 调用父类Parent的构造器,因此系统会自动调用Parent类中的无参构造器来执行初始化。 在父类Parent的无参构造器中,只是调用了display方法来向控制台输出变量i的值,但是结果却为0。 OK,那么到此,如果你知道是为什么,就可以略过以下内容,反之,请耐心的滚动你的鼠标: 当程序运行至1处时,系统为Son实例对象分配了两块内存空间,是的,换言之就是说,Son对象拥有2个名为i的实例变量 声明: 永远记住,构造器只负责对 实例对象的变量进行赋值 ,别无它用。构造器不是用来创建对象的,不是,真的不是! 其实在构造器执行之前,系统已经为该对象分派好内存了,此时此刻,内存中的所有变量值都为默认值,比 如:0,false,null. 言归正传,系统为Son对象分配了2块内存,分别用于存放变量i,其中一个属于Parent类定义的i实例变量,另一个属于 Son类定义的i实例变量,此时此刻,二者的值都为0; 接下来,便是先执行父类的构造器对其值进行赋值操作。Parent中定义i的时候便对其进行了初始化操作,且值为1.接着便 执行display()操作,OK,问题来了人,该方法this.diaplay() 中的this 是谁?对,此时还是不够混乱,OK,我们对Parent做 一点小修改: package com.yjk; public class Parent { //定义一个名为i的实例变量 private int i = 1; public Parent() { System.out.println(this.i); this.display(); } public void display() { System.out.println(i); } } 再次运行,我们可以得到1,0;此刻是不是觉得更加混乱了? 揭秘: 当this在构造器中出现的时候,它所代表的正是当前初始化的实例对象,此时的this位于Son的构造方法中,但是代码们 却出现在父类Parent的构造方法中,那么系统便在Son构造器中,隐式的调用父类Parent构造器中的代码,故,此时的this 是Son对象,既然如此,它输出的却是父类对象的值,这是因为该行代码位于Parent类型中的构造器中,故其编译类型是 Parent,而它实际引用Son了对象. 下面对其进一步进行解释: package com.yjk; public class Parent { //定义一个名为i的实例变量 private int i = 1; public Parent() { System.out.println(this.i); this.display(); System.out.println(this.getClass()); } public void display() { System.out.println(i); } } --------------------------------------------------------------------- “ 当变量的编译时的类型和运行时的类型不同时,通过该变量访问它引用的对象的实例变量时,该实例变量的值由声明该 变量的类型决定。但通过该变量调用它引用的对象的实例方法时,该方法行为将由它实际引用的对象来决定。因此,当 程序访问this.i时,将会访问Parent类中定义的i实例变量,也就是输出1;但执行this.display()方法时,则实际表现出Son对 象的行为,也就是输出Son对象的实例变量,即 0. ”—李刚 看一次可能不能完全接受,多看即便就好了,最后,希望这个帖子能够为你带来一定的收获。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |