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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

  1. class Fu
  2. {
  3.         void run1()
  4.         {
  5.                 System.out.println(" fu run_1 ");
  6.         }
  7.        
  8.         void run2()
  9.         {
  10.                 System.out.println("fu run_2");
  11.         }
  12. }

  13. class Zi extends Fu
  14. {
  15.         void run1()
  16.         {
  17.                 System.out.println("zi run_1");        //对父类的run1 方法的重写
  18.         }
  19.        
  20.         void run3()
  21.         {
  22.                 System.out.println("zi run_3");        //子类自己特有的方法
  23.         }
  24. }

  25. public class DuoTaiTest2
  26. {
  27.         public static void main(String[] args)
  28.         {
  29.                 Fu f = new Zi();        //多态,类型提升
  30.                
  31. f.run1();        //        运行结果是 zi run_1
  32. f.run2();        //  运行结果是 zi run_2 【虽然类型提升,但是运行的依然是zi类的?】
  33.                 f.run3();        // 无法编译。
  34.                
  35.         }
  36. }
复制代码
Q【1】Fu f = new Zi();        //把zi类型提升到Fu类应该没错吧

Q【2】可以帮我分析一下吗?  下面的三个,它们分别是怎么调用和执行的?f.run1();        //        运行结果是 zi run_1
f.run2();        // 运行结果是 zi run_2 【虽然类型提升,但是运行的依然是zi类的?】
f.run3();        // 无法编译。



自己看了几遍,有点乱。还没理清过程。有劳各位帮小弟看看

评分

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

查看全部评分

6 个回复

倒序浏览
创建子类对象后在赋值给父类,属于运行时多态.
此时该对象只能调用父类中方法或子类覆盖父类中的方法,不能调用子类中添加的方法。
当调用那些非父类方法时编译错误所以在Fu f = new Zi(); f.run3();时无法通过编译,
当该对象调用子类和父类中公有的方法时java虚拟机会先查看子类是否覆盖此方法若覆盖则调用子类中的方法若没有覆盖则调用父类中的方法。
所以f.run1();  运行结果是 zi run_1
f.run2(); 运行结果是 zi run_2




求技术分

评分

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

查看全部评分

回复 使用道具 举报
Q【1】:Fu f = new Zi();     是父类引用指向子类对象,没错。Q【2】:f.run1()  //运行结果是:zi run_1  这个没错,因为子类继承了父类,子父类中都有的话,执行子类中的方法。
f.run2();  //你的运行结果是错的吧?你再仔细看一下。这里f调用run2(),而子类中根本就没有run2()这个方法啊,所以它会执行父类中的方法,结果:fu run_2
f.run3();  //创建对象的时候是父类引用指向子类对象,由于父类中没有run3()这个方法,所以编译失败。


在多态中成员函数的特点:
在编译时期(父类引用指向子类对象):参阅引用型变量所属的类中是否有调用的方法,如果有,编译通过,如果没有编译失败。
在运行时期:参阅对象所属的类中是否有调用的方法。
简单总结:成员函数在多态调用时,编译看左边,运行看右边。


评分

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

查看全部评分

回复 使用道具 举报
首先说一下:
f.run1();        //        运行结果是 zi run_1 这个结果你没错
f.run2();        //  运行结果是 zi run_2   这个结果你搞错了 我运行了是fu run_2
----------------------------------------------------------------------------------------------------------
Fu f = new Zi(); 用到了上转型,上转型对象f只能调用子类重写过的方法和父类未被重写的方法(所以有了前两种运行结果),且上转型对象f不能调用子类新定义的成员和方法,所以f对象不能访问子类的新方法run3,它没有权限。所以f.run3无法编译

评分

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

查看全部评分

回复 使用道具 举报
1】Fu f = new Zi(); ,这个你没有错,确实是把Zi提升了,看左边的是Fu,而你创建出来的是Zi,Zi到Fu确实是一个提升的过程这才是多态的体现形式。
f.run1(); //首先说一下结果。是Zi run -1,这是因为多态有一个覆盖的特性,子类继承父类,如果子类重新把父类继承给它的重新定义,那么子类就覆盖了父类,所以是Zi run-1
f.run2(); //这个结果是fu run-2,你的子类继承父类,但是你的子类有没有重新定义覆盖run2这个方法,所以运行的必然是f run-2 再给你说一下,和run1一样,如果这里子类也重新定义覆盖了父类,那结果就是Zi run-2了
f.run3();//这个结果是无法编译,这里是Zi继承父,就是父类有的全给了子类,但是父类又没有继承子类,就是说,父类的东西,都会给子类,而子类有的却不会给父亲,这里就是Zi具备run3()这个功能,但是Fu只有run1 和run2 根本就没有run3 ,不能无中生有的调用它没有的功能

评分

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

查看全部评分

回复 使用道具 举报
我比较赞同第一个回答者 ——————》王新年

创建子类对象后在赋值给父类,属于运行时多态.
此时该对象只能调用父类中方法或子类覆盖父类中的方法,不能调用子类中添加的方法。

所以f.run1();  运行结果是 zi run_1
f.run2(); 运行结果是 zi run_2  ×

      f.run2();运行结果是fu run_2

评分

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

查看全部评分

回复 使用道具 举报
其实我有个最大的疑问,我看了你的代码,你就没写输出zi_run2的语句,怎么会打印出来呢,你上传的代码不全
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马