不可以. 你考虑的问题太多了. "当子类对象引用赋值给父类对象时,它只可以访问父类定义的对象的那一部分",这是编译的要求,比如 class Super{ } class Sub extends Super{ }Super s; 在某个地方你让s指向一个Sub类型的对象了,但对于编译器而言,s的类型为Super,它只能使用 Super及其父类定义的方法. 如果你想使用子类定义的方法,那么先用instanceof判断一下,合适的情况下使用强制类型转换,然后使用子类提供的方法.
我的意思是通过堆栈的角度来解释为什么当把子类的引用赋给父类的时候,只能访问父类定义的对象的那一部分, class A{ int i; } class B extends A{ } class Text{ public static void main(String [] args){ A a = new B(); } }
你考虑的问题太多了.
"当子类对象引用赋值给父类对象时,它只可以访问父类定义的对象的那一部分",这是编译的要求,比如
class Super{
}
class Sub extends Super{
}Super s;
在某个地方你让s指向一个Sub类型的对象了,但对于编译器而言,s的类型为Super,它只能使用 Super及其父类定义的方法.
如果你想使用子类定义的方法,那么先用instanceof判断一下,合适的情况下使用强制类型转换,然后使用子类提供的方法.
当你把父类的引用指向了子类的对象,(你只能通过这个引用操作对象)
对于这个父类的引用而言,
在编译期,编译器只知道它是父类类型,除非你强制类型转换(向下转型),
所以,如果你用父类的引用,去调用子类中独有的方法,
那么必然不能通过编译。没编译通过,也就没有.class文件,
也就没法执行了。而你说的内存角度,正是执行的时候的事情,
解释器在运行过程中才创立内存布局的。
class A{
int i;
}
class B extends A{
}
class Text{
public static void main(String [] args){
A a = new B();
}
}
a在栈中分配,指向堆中的一个对象B
这个对象继承了父类A(B中包含A)
但编译器对于a来说只指向了对象B中的对象A
你调用方法时候只能调用A中的成员。
对于方法来如果子类重写了,那么会调用子类方法。
这也是所谓的多态。