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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© _Water 中级黑马   /  2014-4-4 23:23  /  1529 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 _Water 于 2014-4-6 08:15 编辑

输出结果怎么是3?而不是18或13?

  1. class Foo
  2. {
  3.         public int a;
  4.         public Foo()
  5.         {
  6.                 a=3;
  7.         }

  8.         public void addFive()
  9.         {
  10.                 this.a+=15;
  11.         }
  12. }

  13. class Bar extends Foo
  14. {
  15.         public int a;
  16.         public Bar()
  17.         {
  18.                 a=8;
  19.         }
  20.         public void addFive()
  21.         {
  22.                 a+=5;
  23.         }
  24. }

  25. public class Test
  26. {
  27.         public static void main(String [] args)
  28.         {
  29.            Foo foo=new Bar();
  30.            foo.addFive();
  31.            System.out.println(foo.a);
  32.         }
  33. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
朱神必 + 1

查看全部评分

6 个回复

倒序浏览
父类成员变量中,依然保存父类的元素。
子类成员变量中,依然保存父类的元素。
但父类方法被覆盖时,如果父类成员变量和子类成员变量重名,则只操作子类成员变量。

总结一下:
成员变量的操作,随引用。
覆盖方法的调用,随对象。

评分

参与人数 1技术分 +1 收起 理由
朱神必 + 1

查看全部评分

回复 使用道具 举报
本帖最后由 wuyuecns 于 2014-4-4 23:58 编辑

修改好了。
在Test主函数中做了修改,详见代码注释.同时增加了父类的实例化。以便输出18;
  1. class Foo
  2. {
  3.         public int a;
  4.         public Foo()
  5.         {
  6.                 a=3;
  7.         }

  8.         public  void addFive()
  9.         {
  10.                 this.a+=15;
  11.         }
  12. }

  13. class Bar extends Foo
  14. {
  15.         public int a;
  16.         public Bar()
  17.         {
  18.                 a=8;
  19.         }
  20.         public  void addFive()
  21.         {
  22.                 a+=5;
  23.         }
  24. }

  25. public class Test112
  26. {
  27.         public static void main(String [] args)
  28.         {
  29.            Foo foo=new Bar();                    //向上转型,子类到父类
  30.            Bar bar=(Bar)foo;                         //向下转型
  31.                    bar.addFive();                                //调用方法被覆写的方法
  32.            System.out.println(bar.a);            
  33.                        
  34.                        
  35.                         Foo foo1=new Foo();                //实例化父类对象;
  36.                    foo1.addFive();                            //调用父类方法
  37.                   
  38.                         System.out.println(foo1.a);
  39.                
  40.                 }
  41. }
复制代码



运行结果:13,            18

评分

参与人数 1技术分 +1 收起 理由
朱神必 + 1

查看全部评分

回复 使用道具 举报
本帖最后由 帅哥哥 于 2014-4-5 00:20 编辑

只要知道一个知识点就可以解决这个问题
“Java中,对父类子类中相同的成员变量和相同的成员函数的不同处理”
1.对成员函数,是实实在在的覆盖,也就是重写
     就像楼主代码中的 foo.addFive(); 虽然foo是父类型的引用变量,但指向的是子类对象new Bar(),而addFive()函数又重写了,所以这句调用的是子类的addFive()方法,方法中操作的a是本类也就是Bar中的a
2.对成员变量,java不能覆盖成员变量,父类子类中都有 public int a; ,各自是各自的
    楼主打印的是 foo.a ,而foo是父类型的引用变量,所以,调用的是父类中的a,父类中的a初始化是3,又没有操作过,所以打印的是3,如果楼主打印的是 ((Bar)foo).a ,则打印出来的是13 (8+5),
如果楼主创建的是父类对象 Foo foo = new Foo(); 则打印的 foo.a 是 18


评分

参与人数 1技术分 +1 收起 理由
朱神必 + 1

查看全部评分

回复 使用道具 举报
  1. class Foo
  2. {
  3.         public int a;
  4.         public Foo()//构造函数,对象一建立就执行的语句。
  5.         {
  6.                 a=3;
  7.         }

  8.         public void addFive()
  9.         {
  10.                 this.a+=15;
  11.         }
  12. }

  13. class Bar extends Foo
  14. {
  15.         public int a;
  16.         public Bar()
  17.         {
  18.                 a=8;
  19.         }
  20.         public void addFive()
  21.         {
  22.                 a+=5;
  23.         }
  24. }

  25. public class Test
  26. {
  27.         public static void main(String [] args)
  28.         {
  29.            Foo foo=new Bar();//创建一个多态的对象
  30.            foo.addFive();//foo调用了 子类 addFive方法
  31.            System.out.println(foo.a);
  32.         }
  33. }
  34. /*
  35. 1.对象一建立就执行了 Bar类的构造函数.而构造函数中有一条隐式的super()
  36. 2.指向了父类的构造函数。给予a赋值为3.
  37. 3.你调用 addFive() ,将Bar的a赋值为5.
  38. 4.然后你打印foo.a。 在继承体系中,变量结果看左边,函数结果看右边。所以a的值为3.
  39. */
复制代码

如果想要打印13. 将其向下转型,然后调用 addFive()
如果想要打印18,建立一个Foo对象,调用 adfFive()就可以了

评分

参与人数 1技术分 +2 收起 理由
朱神必 + 2

查看全部评分

回复 使用道具 举报
主函数main()中,Foo foo=new Bar();//创建一个多态的对象
           foo.addFive();//foo调用了 子类 addFive方法 ,而foo是父类型的引用变量,所以,调用的是父类中的a,父类中的a初始化是3,又没有操作过,所以打印的是3,如果楼主打印的是 ((Bar)foo).a ,则打印出来的是13 (8+5),
如果楼主创建的是父类对象 Foo foo = new Foo(); 则打印的 foo.a 是 18

评分

参与人数 1技术分 +1 收起 理由
朱神必 + 1

查看全部评分

回复 使用道具 举报
感谢大家的帮助。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马