A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© ankje 中级黑马   /  2015-3-7 21:46  /  855 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

    先说说我的目的,就是利用已经被向上转型的对象去访问子类中特有的函数,于是通过代码中(===正常部分===)实现了。但我现在想用另外一种办法去达到相同的目的,于是就有了代码中(===试验部分===)。那么我想问问大家,为什么代码中(===试验部分===)会编译失败呢??!!!
  1. class Fu{
  2.         void show(){
  3.                 System.out.println("父类");
  4.         }
  5. }

  6. class Zi extends Fu{       
  7.         void show(){
  8.                 System.out.println("子类");
  9.         }       
  10.         void fun(){
  11.                 System.out.println("子类特有的函数");
  12.         }
  13. }

  14. class Test{       
  15.         public static void main(String[] args){
  16.                
  17.     //================正常部分开始=====================
  18.        
  19.                 Fu f = new Zi(); //向上转型       
  20.                
  21.                 Zi a = new Zi();//创建子类对象
  22.                 a.fun();//调用子类特有函数
  23.                
  24.                 Zi b = (Zi)f;//向下转型
  25.                 b.fun();//调用子类特有函数
  26.                
  27.     //================正常部分结束=====================
  28.                
  29.                
  30.         //================试验部分开始=====================
  31.        
  32.                 f = (Zi)f;//尝试以这种方式向下转型
  33.                 if(f instanceof Zi){
  34.                         System.out.println("f现在是子类");//这里成功打印,说明 f = (Zi)f 这句话应该没什么问题吧
  35.                 }
  36.                 f.fun();//这里编译错误,提示 父类中没有fun()的这个函数
  37.                
  38.         //================试验部分结束=====================
  39.         }       
  40. }
复制代码





评分

参与人数 1技术分 +1 收起 理由
lwj123 + 1 问的不错

查看全部评分

4 个回复

倒序浏览
本帖最后由 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类类型,输出结果也是真
这样来回赋值,它改变的只是指向堆内存中对象的栈内存中的值,并不会改变堆内存中的对象,它该是什么类还是什么类,只不过指向他的指针变化了


评分

参与人数 1技术分 +2 收起 理由
lwj123 + 2

查看全部评分

回复 使用道具 举报
子类可以实现到父类的类型转换,这叫向上转型,但是父类到子类的直接转换是不容许的,因为子类是父类的一个超集,他必须具备父类中包含的所有成员方法,并可能比父类拥有更多的成员方法。
回复 使用道具 举报
这属于多态调用成员函数的问题特点是:编译时看引用性变量所在类中有没有被调用的函数,运行时看实例对象所在类中有没有被调用的函数,即调非静态成员函数时,编译看等号左边,运行看右边。 f.fun()这句话的理解是:调用成员函数的是new Zi()实例对象,而不是引用型变量f(仅仅是一个对象实体的引用地址值),非静态成员函数调用所依赖的是调用它的对象实体,而不是对象实体的引用
和多态时调用成员变量是有区别的
回复 使用道具 举报
Fu f = new Zi(); //向上转型      
f = (Zi)f;//尝试以这种方式向下转型
(Zi)f:表示的是将指向Zi对象f强转为Zi对象
f = (Zi)f:表示的是Zi对象向上转型为Fu
f.fun():这里的f代表的是Fu的对象,fun是父类Fu中不具备的,所以就无法编译通过
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马