黑马程序员技术交流社区

标题: 多态问题 [打印本页]

作者: 古银平    时间: 2012-5-22 21:48
标题: 多态问题
class Fu
{   void method_1()
     {    System.out.println("Fu method_1");     }
    void method_2()
       {    System.out.println("Fu method_2");     }
}
class Zi extends Fu
{    void method_1()
       {    System.out.println("Zi method_1");     }
     void method_3()
       {    System.out.println("Zi method_3");     }
}
class DuoTaiDome
{     public static void main(String[] args)
      {    Fu f=new Zi();
           f.method_3();//编译失败
       Zi z=new Zi();
           z.method_3();//编译成功
     }
}
成员函数在多态调用时,编译看左边,运行看右边。但还是没搞懂,为什么会失败?
作者: 蒋映辉    时间: 2012-5-22 21:50
本帖最后由 蒋映辉 于 2012-5-22 21:54 编辑

编译看左的意思就是,编译的时候,只变异父类的方法,但是运行的时候就会运行子类的方法
Fu f=new Zi();
你这样建立对象的话 f就只能使用父类中有的方法,如果子类中重写了此方法,实际执行的就是子类中的方法。
所以   f.method_3();//编译失败
   父类中没有这个方法  肯定就编译失败了
Zi z=new Zi();
           z.method_3();//编译成功
你这个是建立子类的对象  没有使用多态 就对了  

但实际上可以向下转型 Zi z=(Zi) f;
这样也可以在f这个对象中使用zi的方法了
作者: 付左军    时间: 2012-5-22 21:51
父类没有method—3方法
作者: 王怡然    时间: 2012-5-22 21:57
  1. class Fu
  2. {   void method_1()
  3.       {    System.out.println("Fu method_1");     }
  4.      void method_2()
  5.         {    System.out.println("Fu method_2");     }
  6. }
  7. class Zi extends Fu
  8. {    void method_1()
  9.         {    System.out.println("Zi method_1");     }
  10.       void method_3()
  11. [color=Red]        {    System.out.println("Zi method_3");     }//这是子类特有方法,所以调用无效;[/color]
  12. }
  13. class DuoTaiDome
  14. {     public static void main(String[] args)
  15.        {    Fu f=new Zi();
  16.             f.method_3();//编译失败
  17.         Zi z=new Zi();
  18.             z.method_3();//编译成功
  19.       }
  20. }
复制代码
多态的前提是什么?你要是上课做了笔记我相信你不会问这个问题,
类与类要有继承关系,类与接口要有实现关系,
一定要有方法重写,
需要父类或者接口的引用指向子类的对象,
看代码.红色部分;

作者: 陆建平    时间: 2012-5-22 21:58
Fu f=new Zi();
            f.method_3();//编译失败
编译错误是因为Fu类中没有method_3()方法,改过来就这对了。


作者: 于陈    时间: 2012-5-22 22:09
我想我明白你什么意思了
你这个代码在编译时就会通不过的,
           Fu f=new Zi();
           f.method_3();
这一句,f虽然本质上是子类,内存地址也是指向子类,但你用Fu f就会让编译器以为它是父类,所以下面f想要直接调用子类的方法method_3()是不可以的。如果需要,可以强制转换它为子类类型。
如果这样  Fu f=new Zi();
            f.method_1();
会输出:Zi method_1,这是子类重写(覆盖)的的方法method_1,f是子类的对象。
Fu f=new Zi();
System.out.println(f);
输出:Zi@1fc4bec

就可以验证f本质上是子类的类型的,但是编译器会认为他是父类类型的对象!


作者: 我能驾驭住    时间: 2012-5-22 22:22
首先,这样给你说:父类也是一个“类”,他只是多了一个“可被继承(extends)”的特性,父类:依我的个人理解他就是把很多公共方法放到一起然后封装成一个“类”成为所谓的父类。这样,如果再有类需要用到他所包含的某些公共的方法的时候,就可以直接继承这个父类了避免了不必要的重复符合  write once and only once 的良好习惯。 当出现 父类 对象=new 子类()时  你可以这样想“子类 是被父类 ‘罩’着的。” 这样可以实例化一个父类对象。请看清楚,我说的是可以实例化一个父类对象,那这样的话,子类内含的子类自己的方法就会被屏蔽掉。这样的话,你就访问不到子类中的方法了。所以,你上边的那句编译错误也就能解释了。
作者: 余宏    时间: 2012-5-22 23:21
f.method_3();//编译失败是因为父类没有定义 f.method_3()方法,而该方法定义在子类,所以父类对象不能访问该方法,而子类对象可以。
作者: 李红飞    时间: 2012-5-23 10:32
class Fu
{   void method_1()
     {   
                 System.out.println("Fu method_1");   
         }
    void method_2()
       {   
                System.out.println("Fu method_2");   
           }
}
class Zi extends Fu
{      
        void method_1()                          //子类重写父类方法,当发生多态是,父类对象会调用子类重写的方法
       {    System.out.println("Zi method_1");     }
     void method_3()                          //子类自已定义的方法
       {    System.out.println("Zi method_3");     }
}
class DuoTaiDome
{     public static void main(String[] args)
      {    Fu f=new Zi();      //此处子类对象由父类实例化,由于父类没有method_3()方法,所以会编译失败
           f.method_3();       //编译失败
            Zi z=new Zi();    //子类的对象调用子类的方法 ,没有使用多态编译成功
           z.method_3();//编译成功
     }
}
作者: 杨康    时间: 2012-5-23 11:25
class DuoTaiDome
{     public static void main(String[] args)
      {    Fu f=new Zi();
           f.method_3();//编译的时候他会在Fu类中,有没有method_3(),没有就会报错。
       Zi z=new Zi();
           z.method_3();//Zi类中有method_3(),故编译可以通过。
     }
}




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