父类引用指向子类对象的问题

Java code?

1
FatherClass f =  new  SonClass()



当父类引用f指向其子类的对象的时候,通过f无法访问专属于子类对象的成员。

假如子类中有对父类方法的重写,那么根据多态机制,通过f访问这个方法的时候实际访问的是子类中重写的方法。

问题是如果子类重写的方法中访问了专属于子类的成员变量,这时候通过父类引用f还可以调用那个被重写的方法吗?






当父类引用f指向其子类的对象的时候,通过f无法访问专属于子类对象的成员。
为什么这样不可以?LZ有没有想过,因为f是FatherClass,所以编译器只知道f拥有FatherClass.class的信息,FatherClass.class以外的信息,编译器不知道,而子类的对象成员是在SonClass.class里,也就是说在FatherClass.class以外,所以f无法访问子类的对象成员

假如子类中有对父类方法的重写,那么根据多态机制,通过f访问这个方法的时候实际访问的是子类中重写的方法。
为什么这样可以?上面说了,f只能访问FatherClass.class的信息(注意这里指的是编译期编译器只知道f是FatherClass类型,不知道f具体指向什么对象,运行期才知道指向什么对象),而子类重写的方法,父类中也存在,即SonClass.class重写的方法,FatherClass.class里也有(如果SonClass.class里有但是FatherClass.class里没有的方法,f也不能直接调用),所以f可以访问,但是调用的时候(注意这里指的是运行期),f实际指向的是SonClass对象,所以调用的是SonClass对象的方法。

问题是如果子类重写的方法中访问了专属于子类的成员变量,这时候通过父类引用f还可以调用那个被重写的方法吗?
可以,要分清编译期和运行期,编译期是编译器检查语法和类型,运行期是解析器解析伪代码为机器指令而执行,编译期编译器会检查f的访问范围,也就是f的访问不超过FatherClass.class的信息就不会出错,运行期解析器会解析方法的代码指令,因为f指向子类对象,所以会解析子类重写的方法代码指令,而子类对象的内存空间是包含子类的成员变量的空间的,所以也不存在子类成员变量没有分配内存的问题,所以可以调用。

LZ要分清楚,为什么会生成FatherClass.class和SonClass.class两个文件,既然是生成两个文件,那当然是那个文件被使用,就可以访问那个文件的信息。编译期编译器只知道f是FatherClass类型(至于f=什么,那是运行期,因为不运行=就不会执行),所以会检查f是否在FatherClass.class的范围,而运行期,f指向的是SonClass对象,也就是内存的对象是SonClass.class的信息,所以执行的是SonClass.class的代码指令。

你可能感兴趣的:(父类引用指向子类对象的问题)