黑马程序员技术交流社区

标题: 多态的疑惑 [打印本页]

作者: 杜正华    时间: 2012-10-17 11:20
标题: 多态的疑惑
本帖最后由 杜正华 于 2012-10-18 10:59 编辑
  1. package com.itcast.practise;

  2. public class Demo8 {
  3.   public static void main(String[] args) {
  4.                 // TODO Auto-generated method stub
  5.             
  6.                 Father f = new Sun();
  7.                 f.speak();  
  8.                 f.smoke();
  9.                 //f.play();  为什么不可以?
  10.                 Sun s = (Sun)f;
  11.                 s.speak();
  12.                 s.smoke();
  13.                 s.play();
  14.   }
  15. }
  16. class Father{
  17.         void speak(){
  18.                 System.out.println("父亲说话方法...");
  19.         }
  20.         void smoke(){
  21.                 System.out.println("父亲抽烟方法...");
  22.     }
  23. }
  24. class Sun extends Father{
  25.         void speak(){
  26.                 System.out.println("儿子说话方法...");
  27.         }
  28.         void play(){
  29.                 System.out.println("儿子玩的方法...");
  30.         }
  31. }
复制代码
既然f指向new Sun()的引用,那么为什么f.play()不可以?很疑惑...请画出上述代码在内存中的表现图
作者: 黑马乔荣柱    时间: 2012-10-17 11:28
因为play()是子类Sun的独有的方法,而不是继承自父类的,父类的引用f要想调用子类Sun独有的的方法,必须将父类引用强转为子类引用
Sun f1=(Sun)f;
然后用f1去调用play方法就可以了
作者: 马良    时间: 2012-10-17 11:49
要不我用毕老师讲课时候的例子给你讲解一下吧。

儿子继承了父亲的说话功能(他说的是年轻人的话),抽烟功能,当然还有自己的玩的功能
父亲有自己说话的功能(说中年人的话),还有抽烟功能,但是不会玩

Father f = new Sun(); 这句话理解一下,父亲的朋友来了,父亲不在家,儿子在家是一个实体(相当于new Sun()),儿子就化妆成了父亲
f.speak();  然后,父亲的朋友要跟“父亲”聊天了,这时候,这个“父亲”说的当然是年轻人的话,他肯定说不出中年人的话啊!
f.smoke();这个很好理解,父亲儿子都会抽烟,而且也没有进行复写。
f.play();   这时候,父亲的朋友走了,但是儿子的妆还没卸下来,儿子的朋友来找他玩了,可是他朋友看到儿子,还以为是父亲,肯定不会跟他玩啊,儿子打扮成父亲的样子肯定也不好意思跟他朋友玩吧!
Sun s = (Sun)f;  好,这时候,儿子对他朋友说,你等一下,然后就去把妆卸下来了,这会儿,就开开心心的出去玩了——s.play();

{:soso_e113:}





作者: 马良    时间: 2012-10-17 12:01
你可以回去看一下视频,回顾一下老师讲过的内容
黑马程序员_毕向东_Java基础视频教程第08天-05-面向对象(多态中成员的特点)  从04:15开始看,
作者: 王亚运    时间: 2012-10-17 12:46
学习 了。
之前我也是很迷惑。。。


作者: 杜正华    时间: 2012-10-17 13:07
希望能画出图来解释一下,按毕老师的方法编译看左边,运行看右边。到底内存中是怎么表现的。。。。
毕老师的视频很强大,但是有的细节还是没讲到。。。
作者: 杜正华    时间: 2012-10-17 13:08
希望能画出图来解释一下,按毕老师的方法编译看左边,运行看右边。到底内存中是怎么表现的。。。。
毕老师的视频很强大,但是有的细节还是没讲到。。。
作者: 陈军    时间: 2012-10-17 14:15
本帖最后由 陈军 于 2012-10-17 14:23 编辑

多态的弊端: 父类的引用不能访问子类独特的成员。
father类没有play()方法,该方法是子类特有的 。
所以你不能这么访问

毕老师说的对于非静态成员函数,编译看左边,运行看右边是这样的。
图没怎么画过。。文字吧。

解答: 左边和右边是基于=号左右。 也就是Father f=new Son();这个的左右2边。
    而f.play(). 编译的时候看左边,就是说编译时,看f对象有没有play()方法。而父类Father类明显没有。

  运行看右边意思是,左边符合了(即父类有该方法),运行时实际用的是new Sun()对象的play()方法
  

作者: 黄佳    时间: 2012-10-17 14:58


     父类引用指向子类对象时   要想调用子类特有的方法   必须向下转型为该子类类型  才可以调用子类方法
      即:
      Father f = new Sun();
      Sun s = (Sun)f;
      s.play;






欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2