黑马程序员技术交流社区
标题:
关于向下转型的问题
[打印本页]
作者:
ankje
时间:
2015-3-7 21:46
标题:
关于向下转型的问题
先说说我的目的,就是利用已经被向上转型的对象去访问子类中特有的函数,于是通过代码中(===正常部分===)实现了。但我现在想用另外一种办法去达到相同的目的,于是就有了代码中(===试验部分===)。那么我想问问大家,为什么代码中(===试验部分===)会编译失败呢??!!!
class Fu{
void show(){
System.out.println("父类");
}
}
class Zi extends Fu{
void show(){
System.out.println("子类");
}
void fun(){
System.out.println("子类特有的函数");
}
}
class Test{
public static void main(String[] args){
//================正常部分开始=====================
Fu f = new Zi(); //向上转型
Zi a = new Zi();//创建子类对象
a.fun();//调用子类特有函数
Zi b = (Zi)f;//向下转型
b.fun();//调用子类特有函数
//================正常部分结束=====================
//================试验部分开始=====================
f = (Zi)f;//尝试以这种方式向下转型
if(f instanceof Zi){
System.out.println("f现在是子类");//这里成功打印,说明 f = (Zi)f 这句话应该没什么问题吧
}
f.fun();//这里编译错误,提示 父类中没有fun()的这个函数
//================试验部分结束=====================
}
}
复制代码
作者:
z47057554
时间:
2015-3-8 03:48
本帖最后由 z47057554 于 2015-3-8 04:05 编辑
试验部分的问题
你的f是由父类定义的指针,f=(Zi)f;相当于
fu f2=(Zi)f;//这跟 fu f=new Zi();是一个道理
f2.fun();
(Zi)f 是向下转型,但转完后你又把它赋给了父类指针,这又是一次向上转型,做的是无用功,结果还是只能调用父类的方法
至于你打印的那句话是,哪怕你把在前面的f=(Zi)f;去掉,它也不会变化,这里不是看前面的指针是谁,而是看指针指向的对象是谁。
你即便这样做
Object obj=(Zi)f;
然后,再输出判断obj是否Zi类类型,输出结果也是真
这样来回赋值,它改变的只是指向堆内存中对象的栈内存中的值,并不会改变堆内存中的对象,它该是什么类还是什么类,只不过指向他的指针变化了
作者:
硫氢化铁
时间:
2015-3-8 07:49
子类可以实现到父类的类型转换,这叫向上转型,但是父类到子类的直接转换是不容许的,因为子类是父类的一个超集,他必须具备父类中包含的所有成员方法,并可能比父类拥有更多的成员方法。
作者:
白春秋
时间:
2015-3-8 08:19
这属于多态调用成员函数的问题特点是:编译时看引用性变量所在类中有没有被调用的函数,运行时看实例对象所在类中有没有被调用的函数,即调非静态成员函数时,编译看等号左边,运行看右边。 f.fun()这句话的理解是:调用成员函数的是new Zi()实例对象,而不是引用型变量f(仅仅是一个对象实体的引用地址值),非静态成员函数调用所依赖的是调用它的对象实体,而不是对象实体的引用
和多态时调用成员变量是有区别的
作者:
lwj123
时间:
2015-3-8 14:55
Fu f = new Zi(); //向上转型
f = (Zi)f;//尝试以这种方式向下转型
(Zi)f:表示的是将指向Zi对象f强转为Zi对象
f = (Zi)f:表示的是Zi对象向上转型为Fu
f.fun():这里的f代表的是Fu的对象,fun是父类Fu中不具备的,所以就无法编译通过
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2