关于"多态"形式的成员变量问题(关于this究竟代表的案例)
2017-03-13 10:16
211 查看
我们知道,父类是不能访问子类的实例变量的。但这里有一个特殊的案例
结果却出人意料,并不是2, 2.而是2, 0.
分析:在①出代码,新建了Sub对象,在Sub类的构造函数中,先隐式调用Base类的无参构造函数。在分析Base的构造函数之前,我们首先要明白三点:
1)Java类的对象并不是由构造函数创建的,而是在构造函数赋初值之前,就已经给类成员变量分配了内存空间,并且内存内的值为空值。而且类中的定义时即赋值的成员变量和非静态代码块中初始化元素,都是先分配内存(存储默认值),然后在归并到构造函数中赋初始值,并按先后顺序排列在构造函数原本的代码之前。
2)关于子类与父类有多个同名实例变量的问题,要知道,子类的实例变量并不能覆盖父类的同名实例变量。所以在实例化Sub类时,要先分配两块内存空间,用来存储父类的i和子类的i,这时两个i的值都为0。
3)当this在构造器中时,代表正在初始化的对象。从源代码来看,this在Base的构造器中执行。但是实际上,现在正在初始化的Java类是Sub,因为是在Sub的构造器中隐式地调用了父类的默认构造器,所以this是Sub类,这一点可以从this.getClass()验证。
那么问题来了,this代表Sub类,但this.i却输出2,而this.display()却输出0。
这是因为this位于Base的构造器中,它的编译类型是Base,但是它引用的对象则是一个Sub类型,即它的运行时类型是一个Sub类型,这一点可以由this.test()验证,因为这回编译不通过。
总结:当变量的编译时类型和运行时类型不同时,当通过该变量来访问它所引用的对象的实例变量时,该实例变量的值由声明它的类型决定,但当通过该变量来访问它所引用对象的实例方法时,该方法行为将由它所引用的对象类型决定。
所以this.i的值为Base中的i,this.display()为Sub中的方法,i为0.
class Base { private int i = 2; public Base(){ System.out.println(this.i); this.display(); //System.out.println(this.getClass()); //this.test(); } public void display(){ System.out.println(i); } } public class Sub extends Base { private int i = 22; public Sub(){ i = 222; } public void display(){ System.out.println(i); } public static void main(String[] args) { new Test(); ① } public void test(){ } }
结果却出人意料,并不是2, 2.而是2, 0.
分析:在①出代码,新建了Sub对象,在Sub类的构造函数中,先隐式调用Base类的无参构造函数。在分析Base的构造函数之前,我们首先要明白三点:
1)Java类的对象并不是由构造函数创建的,而是在构造函数赋初值之前,就已经给类成员变量分配了内存空间,并且内存内的值为空值。而且类中的定义时即赋值的成员变量和非静态代码块中初始化元素,都是先分配内存(存储默认值),然后在归并到构造函数中赋初始值,并按先后顺序排列在构造函数原本的代码之前。
2)关于子类与父类有多个同名实例变量的问题,要知道,子类的实例变量并不能覆盖父类的同名实例变量。所以在实例化Sub类时,要先分配两块内存空间,用来存储父类的i和子类的i,这时两个i的值都为0。
3)当this在构造器中时,代表正在初始化的对象。从源代码来看,this在Base的构造器中执行。但是实际上,现在正在初始化的Java类是Sub,因为是在Sub的构造器中隐式地调用了父类的默认构造器,所以this是Sub类,这一点可以从this.getClass()验证。
那么问题来了,this代表Sub类,但this.i却输出2,而this.display()却输出0。
这是因为this位于Base的构造器中,它的编译类型是Base,但是它引用的对象则是一个Sub类型,即它的运行时类型是一个Sub类型,这一点可以由this.test()验证,因为这回编译不通过。
总结:当变量的编译时类型和运行时类型不同时,当通过该变量来访问它所引用的对象的实例变量时,该实例变量的值由声明它的类型决定,但当通过该变量来访问它所引用对象的实例方法时,该方法行为将由它所引用的对象类型决定。
所以this.i的值为Base中的i,this.display()为Sub中的方法,i为0.
相关文章推荐
- 关于this究竟代表的案例
- 关于空指针类型的类变量的成员函数访问的问题
- php关于private、public成员变量访问问题
- 关于无默认构造函数的类的对象作为成员变量的问题
- 关于java中实体类成员变量命名的问题
- 关于内部类中成员变量和外部类成员变量的问题
- 关于属性和成员变量的问题
- 关于百度地图SDK在" SDKInitializer.initialize(this);"初始化报空指针的问题
- 一个关于成员变量的多态问题
- 一个关于类的数组成员变量问题
- 关于VS2008 中添加成员变量提示 此网站的某个加载项运行失败 请检查“Internet选项”中的安全设置是否存在潜在冲突 问题解决办法
- [C++] 关于子类声明与父类同名同类型的成员变量的问题
- 关于VS2008 中添加成员变量提示 此网站的某个加载项运行失败 请检查“Internet选项”中的安全设置是否存在潜在冲突 问题解决办法
- 关于构造函数析构函数以及成员变量内存分配顺序的一些问题
- 关于"中文变量"与"VB与C#"混写的问题
- 关于java中对于成员变量的引用问题
- 关于成员变量和局部变量是否都会被默认初始化的问题
- 静态成员变量初始化问题。关于 error LNK2005 static int:已经在***.obj中定义
- 注意访问器中的一个小细节,关于有访问器没有成员变量的问题
- 关于c++的类中成员变量初始化问题+初始化列表中对应顺序问题!