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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© HM李超 高级黑马   /  2013-3-22 03:27  /  1842 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

演示代码:
  1. class BaseClass
  2. {
  3.         public int book = 6;
  4.         public void base()
  5.         {
  6.                 System.out.println("父类的普通方法");
  7.         }
  8.         public void test()
  9.         {
  10.                 System.out.println("父类的被覆盖的方法");
  11.         }
  12. }
  13. class  SubClass extends BaseClass
  14. {
  15.         public String book = "Java核心技术";             //重新定义一个book实例属性覆盖父类的book实例属性
  16.         public void test()
  17.         {
  18.                 System.out.println("子类的覆盖父类的方法");
  19.         }
  20.         public void sub()
  21.         {
  22.                 System.out.println("子类的普通方法");
  23.         }
  24.         public static void main(String[] args)
  25.         {
  26.                 BaseClass bc = new BaseClass();       //编译时类型和运行时类型完全一样,不存在多态
  27.                 System.out.println(bc.book);          //输出6
  28.                 bc.base();                                                          //两次都执行BaseClass的方法
  29.                 bc.test();
  30.                 System.out.println();
  31.                 SubClass sc = new SubClass();         //编译时类型和运行时类型完全一样,不存在多态
  32.                 System.out.println(sc.book);          //输出“Java核心技术”
  33.                 sc.base();                                                          //调用从父类继承到的base方法
  34.                 sc.test();                            //调用当前类的test方法
  35.                 System.out.println();
  36.                 BaseClass ploymorphicBc = new SubClass();  //编译时和运行时的类型不同,多态
  37.                 System.out.println(ploymorphicBc.book);    //输出6,表明访问的是父类属性
  38.                 ploymorphicBc.base();                      //调用父类继承到的base方法
  39.                 ploymorphicBc.test();                      //调用当前类的test方法
  40.                 //ploymorphicBc.sub();       //编译出错,因为变量编译时是BaseClass类型,BaseClass类没有sub方法
  41.         }
  42. }
复制代码
运行结果:


问题:最后一行代码为什么编译的时候就出错了?sub也是子类的方法,test也是,为什么父类引用ploymorphicBC
          能调用子类的test方法,调用sub方法时编译就出错,有点小绕,谢谢给个解释!

点评

如果你的问题已经得到解决,请及时将主题改为[已解决],如果还有问题请继续提问,谢谢  发表于 2013-3-22 09:41

评分

参与人数 1技术分 +1 收起 理由
贾文泽 + 1

查看全部评分

4 个回复

倒序浏览
我是这么理解的哈,仅供参考.因为java分编译期和运行期.
BaseClass ploymorphicBc = new SubClass();  对编译器来说,他的类型就是父类的BaseClass,因为父类有test方法,所以编译通过了.
然后运行时,实际上它是指向子类对象,子类本身复写了test方法,所以就执行了子类的test.
而 BaseClass ploymorphicBc = new SubClass(); 去调用sub方法,对编译器来说,BaseClass这个类是没有sub方法的,编译直接不通过.....也不用管他指向的是子类对象还是父类对象了....

评分

参与人数 1技术分 +1 收起 理由
贾文泽 + 1

查看全部评分

回复 使用道具 举报
这个问题毕老师的视频中讲过
BaseClass ploymorphicBc = new SubClass();  
付类的引用指向子类的对象,在编译的时候看等号左边运行时看等号右边,而在调用子类中sub方法时,父类中没有sub方法,因此会编译失败
而ploymorphicBc.base(); 和ploymorphicBc.test();这两句调用的base和test方法父类中都有,所以编译时能通过

评分

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

查看全部评分

回复 使用道具 举报
对于多态,我是这样理解的哈:如果父类有的方法,子类就会覆盖,父类没有的方法,子类就隐藏。当向下转型变会自己的时候,就会显示出来。
所以,你在//ploymorphicBc.sub();  前面加多一句:SubClass subc = (SubClass) ploymorphicBc;然后再调用

评分

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

查看全部评分

回复 使用道具 举报
因为子类其实是一种特殊的父类,因为Java允许把一个子类对象直接赋给一个父类引用变量,无须任何类型转换,或者被称为向上转型,向上转型是由系统自动完成的。
Java引用变量有两个类型,一个是编译时的类型,一个是运行时的类型。编译时的类型是由声明该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定。如果编译时类型和运行时类型不一致,就会出现所谓的多态。
所以BaseClass ploymorphicBc = new SubClass();  在编译的时候,sub不是编译时类型的方法,所以编译同不过。
当通过引用变量来访问其包含的实列属性时,系统总是试图访问它编译时类所定义的属性,而不是它运行时类所定义的属性。
希望对你有所帮助!

评分

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

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马