BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / java / #41353同步于 2015/6/5
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖

关于向上转型

liu487639
2015/6/5镜像同步23 回复
子类向上转型为父类时,比如Parent parent= Son son;这里son是实例对象,那么问题来了,parent是指向son的一个引用,还是新建了一个对象并把son中的对应的成员和方法用来初始化? 然而在调试的时候,我却看到parent对象中有son中的成员,但实际上自己并没有定义;当然,在代码中你是无法使用它们的; 那么,parent到底是什么?是一个把son对应值拿来初始化的parent对象,还是对son的一个引用?或者是一个Son对象,但编译器不允许程序员使用除了panent以外的其他成员? PS:总结一下:可以使用子类的覆写的方法和父类的成员变量 编程思想中明确说这是一个指向子类对象的引用,并且在执行时才会将调用的方法和方法的主体绑定到一起,也就是后期绑定;到这里似乎解决了多态的问题; 然而,在使用成员变量时,却遇到了问题。也就是楼下给的代码,使用成员变量时给出的是父类的成员变量而不是子类,至于为什么,也许真如楼下所说属性是静态绑定的(前期绑定)。 ------------------------我是神奇的分割线6.16补充---------------------------- 昨晚和同事谈到这个问题,说JVM对于类的成员变量和方式(静态的除外)是用两种不同的方式来存储的,对于成员变量,在声明这个类时,内存中已经有了这个变量(或者说域,可还是觉得成员变量更容易理解),方法却没有; 关于父类引用指向子类对象,这个指向是一块内存空间,JVM机制保证父类无法调用子类对象的成员变量; 貌似到这里已经解决楼下那个奇怪代码的问题,如果有新的进展,我会接着补充~
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
liu487639机器人#1 · 2015/6/5
自问自答吧,在java中想要新建一个对象,必须使用关键字new,所以上面的例子中,我更倾向于只是一个对son的引用,只是编译器不允许你调用该引用中不属于parent中的成员和方法。其实在调试的时候,也能看出来,因为这一步是一步跳过的,并没有出现调用构造函数或者赋值等行为。
dss886机器人#2 · 2015/6/5
只是引用吧…parent一直都是Son类的 【 在 liu487639 (年轻有为小正太) 的大作中提到: 】 : 子类向上转型为父类时,比如Parent parent= Son son;这里son是实例对象,那么问题来了,parent是指向son的一个引用,还是新建了一个对象并把son中的对应的成员和方法用来初始化? : 然而在调试的时候,我却看到parent对象中有son中的成员,但实际上自己并没有定义;当然,在代码中你是无法使用它们的; : 那么,parent到底是什么?是一个把son对应值拿来初始化的parent对象,还是对son的一个引用?或者是一个Son对象,但编译器不允许程序员使用除了panent以外的其他成员?
liu487639机器人#3 · 2015/6/5
确实只是引用,而且是完整的引用,但不能使用Parent类未定义的成员,这应该是编译过程中的一种机制 【 在 dss886 的大作中提到: 】 : 只是引用吧…parent一直都是Son类的 :
Lamperouge机器人#4 · 2015/6/5
我的理解是把Son暂时看成了parent 如果强制转为son的话就可以调用 son中的成员(了吧?)
feilengcui机器人#5 · 2015/6/5
是引用,通过运行时类型信息可以将引用转换为子类,就可以访问子类的成员了。这是静态语言实现动态的一种手段 通过『我邮2.0』发布
soseso机器人#6 · 2015/6/9
我理解的时候是参照的C++的动态绑定
liu487639机器人#7 · 2015/6/9
动态绑定是在执行的时候才确定么? 【 在 soseso 的大作中提到: 】 : 我理解的时候是参照的C++的动态绑定
Monologue机器人#8 · 2015/6/9
看看这个例子~或许会有新想法~~~ class Parent{ int a =1; public String method() { return "Parent"; } } class Son extends Parent{ int a =2; public String method() { return "Son"; } } public class ClassExtends { public static void main(String[] args) { Parent p = new Parent(); System.out.println(p.a + " "+p.method());// 1 Parent Parent p2 = new Son(); System.out.println(p2.a + " "+p2.method());// 1 Son Son p3 = new Son(); System.out.println(p3.a + " "+p3.method());// 2 Son Son p4 = (Son) p2; System.out.println(p4.a + " "+p4.method());// 2 Son } }
soseso机器人#9 · 2015/6/9
【 在 liu487639 的大作中提到: 】 : 动态绑定是在执行的时候才确定么? 是的,使用基类对象引用派生类对象多数时候的目的就是要触发多态,这样基类对象就可以使用派生类对象重写的方法了。C++的编译器会在运行时确定基类对象使用的方法是基类的还是派生类的。参考c++ primer 15.2.3章节。