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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© vermouth 中级黑马   /  2015-1-14 11:32  /  1194 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 czwanglei 于 2015-1-14 13:51 编辑

昨天看到个问题是这样的:
  1. class Parent {
  2.      private int eatID=0;
  3.      public Parent(){
  4.          System.out.println("Parent is creating..");
  5.          eat();
  6.      }
  7.      public void eat(){
  8.         System.out.println("Parent is eat: "+eatID);
  9.      }

  10. }

  11. class Son extends Parent {
  12.      private int eatID=1;
  13.      public Son(){
  14.          System.out.println("Son is creating..");
  15.          eat();
  16.      }
  17.      public void eat(){
  18.          System.out.println("Son is eat: "+eatID);
  19.      }
  20.    

  21. }

  22. class Test {
  23.   @SuppressWarnings(value={"unused"})
  24.      public static void main(String[] args){
  25.          Parent p;
  26.                  p=new Son();
  27.      }
  28. }
复制代码
这个运行的输出是:
Parent is creating..
Son is eat: 0
Son is creating..
Son is eat: 1


这个问题很典型,在很多时候如果我们不注意就会犯很大的错误。
这里涉及到父类引用指向子类对象的问题。

在子类对象生成时,构造器会默认调用父类的构造器产生一个隐藏父类对象,所以会打印第一行。
父类引用指向一个子类对象:
       首先,他是一个父类引用,所以拥有的是父类中的方法,如果子类重写了父类的方法,则会自动调用子类方法。
       其次,成员变量是不可继承的,所以父类构造器中调用的eat方法使用的eatID是父类中的变量,值是0,。
所以打印了第二行。
第三行和第四行相信不用解释啦。

最后详细解释一下Parent p=new Son() ;
这样的写法满足java语言的多态,为我们开发带来很大便利。p既有子类对象的强大功能,又保证了父类的共性。

对于多态,可以总结以下几点

一、使用父类类型的引用指向子类的对象;
二、该引用只能调用父类中定义的方法和变量;
三、如果子类中重写了父类中的一个方法,那么在调用这个方法的时候,将会调用子类中的这个方法;
四、变量不能被重写


简单的说就是:
       当父类中的一个方法只有在父类中定义而在子类中没有重写的情况下,才可以被父类类型的引用调用;
       对于父类中定义的方法,如果子类中重写了该方法,那么父类类型的引用将会调用子类中的这个方法,这就是动态连接。


       直观的记法是:在家中,父亲对于有把握让儿子做的事情就交给儿子去做,如果儿子太小了做不了,就自己亲自做。但如果儿子想尝试新科技,而自己又不懂了,就不允许儿子去做,很简单,父亲就是这么封建,自己不会的也不让儿子做。但至于吃饭的时候爱吃什么,就各自去决定吧,也就是变量不继承。


        这样解释,以后还会犯错误么~

评分

参与人数 1技术分 +1 收起 理由
czwanglei + 1 赞一个!

查看全部评分

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马