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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 古银平 中级黑马   /  2012-5-22 21:48  /  2356 人查看  /  9 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

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();//编译成功
     }
}
成员函数在多态调用时,编译看左边,运行看右边。但还是没搞懂,为什么会失败?

9 个回复

倒序浏览
本帖最后由 蒋映辉 于 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的方法了
回复 使用道具 举报
父类没有method—3方法
回复 使用道具 举报
  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. }
复制代码
多态的前提是什么?你要是上课做了笔记我相信你不会问这个问题,
类与类要有继承关系,类与接口要有实现关系,
一定要有方法重写,
需要父类或者接口的引用指向子类的对象,
看代码.红色部分;
回复 使用道具 举报
Fu f=new Zi();
            f.method_3();//编译失败
编译错误是因为Fu类中没有method_3()方法,改过来就这对了。

回复 使用道具 举报
我想我明白你什么意思了
你这个代码在编译时就会通不过的,
           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本质上是子类的类型的,但是编译器会认为他是父类类型的对象!

回复 使用道具 举报
首先,这样给你说:父类也是一个“类”,他只是多了一个“可被继承(extends)”的特性,父类:依我的个人理解他就是把很多公共方法放到一起然后封装成一个“类”成为所谓的父类。这样,如果再有类需要用到他所包含的某些公共的方法的时候,就可以直接继承这个父类了避免了不必要的重复符合  write once and only once 的良好习惯。 当出现 父类 对象=new 子类()时  你可以这样想“子类 是被父类 ‘罩’着的。” 这样可以实例化一个父类对象。请看清楚,我说的是可以实例化一个父类对象,那这样的话,子类内含的子类自己的方法就会被屏蔽掉。这样的话,你就访问不到子类中的方法了。所以,你上边的那句编译错误也就能解释了。
回复 使用道具 举报
余宏 中级黑马 2012-5-22 23:21:21
8#
f.method_3();//编译失败是因为父类没有定义 f.method_3()方法,而该方法定义在子类,所以父类对象不能访问该方法,而子类对象可以。
回复 使用道具 举报
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();//编译成功
     }
}
回复 使用道具 举报
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(),故编译可以通过。
     }
}
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马