黑马程序员技术交流社区

标题: 求解 [打印本页]

作者: _Water    时间: 2014-4-4 23:23
标题: 求解
本帖最后由 _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. }
复制代码

作者: 水蓝    时间: 2014-4-4 23:29
父类成员变量中,依然保存父类的元素。
子类成员变量中,依然保存父类的元素。
但父类方法被覆盖时,如果父类成员变量和子类成员变量重名,则只操作子类成员变量。

总结一下:
成员变量的操作,随引用。
覆盖方法的调用,随对象。
作者: wuyuecns    时间: 2014-4-4 23:45
本帖最后由 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


作者: 帅哥哥    时间: 2014-4-5 00:13
本帖最后由 帅哥哥 于 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



作者: 黄泉    时间: 2014-4-5 14:06
  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()就可以了
作者: ifuzhen    时间: 2014-4-5 21:32
主函数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
作者: _Water    时间: 2014-4-6 08:15
感谢大家的帮助。




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