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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 黄小橙 金牌黑马   /  2014-8-26 21:01  /  2175 人查看  /  19 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 黄小橙 于 2014-8-27 09:53 编辑

视频里毕老师讲过
在多态中成员变量的特点:只看引用变量所属的类。即无论编译和运行,都参考左边(引用型变量所属的类)。
--------------------------------------------------------------------------------------------------------------------
那为什么下面代码的答案不是B C 2 而是B C 5呢?
按照我的理解是:Super类里面的i变量通过 构造函数的初始化后就变成2了。然后Demo类里面的i变量通过构造函数初始化后就变成了5,
而d.i调用的i是Super类里面的,那应该是i=2啊。。。求大神们解答一下。
-------------------------------------------------------------------------------------------
class Super
{
    int i = 0;
    public Super()
    {
        System.out.println("B");
        i+=2;
    }
}

class Demo extends Super
{
    public Demo(String a)
    {
        System.out.println("c");
        i = 5;
    }
    public static void main(String[] args)
    {
        int i = 4;
        Super d = new Demo("A");
        System.out.println(d.i);
    }
}

评分

参与人数 1技术分 +1 收起 理由
付江涛 + 1 神马都是浮云

查看全部评分

19 个回复

倒序浏览
{:3_52:}有哥们帮忙解答一下么。。。
回复 使用道具 举报
好混乱,我整理下~
回复 使用道具 举报
本帖最后由 noiary 于 2014-8-26 21:49 编辑

                                       1
回复 使用道具 举报
noiary 发表于 2014-8-26 21:28
好混乱,我整理下~

编译看左边,运行看右边,
回复 使用道具 举报
noiary 发表于 2014-8-26 21:40
想画图来着,然后发现...我不会画...

我想 , 顺序应该是这样的:

你的意思是Demo类构造函数中操作的i变量和父类构造函数中操作的i变量是同一个i吗
回复 使用道具 举报
本帖最后由 黄小橙 于 2014-8-27 09:52 编辑
舍我其谁 发表于 2014-8-26 21:41
编译看左边,运行看右边,

编译看左边,运行看右边。是成员函数在多态调用时的吧。 d.i是调用变量,变量是无论编译和运行都看引用型变量所属的类。
回复 使用道具 举报
noiary 高级黑马 2014-8-26 21:50:25
8#
黄小橙 发表于 2014-8-26 21:46
你的意思是Demo类构造函数中操作的i变量和父类构造函数中操作的i变量是同一个i吗 ...

你这么疑问我也不确定啦 哈哈  

这是个值得探讨的问题... 我们可以做实验证明一下
回复 使用道具 举报
黄小橙 发表于 2014-8-26 21:48
编译看左边,运行看右边。是成员函数在多态调用时的吧。 d.i是调用静态,静态是无论编译和运行都看引用型 ...

你是在静态函数里调用没错,但是你是用对象调用的,
回复 使用道具 举报
黄小橙 发表于 2014-8-26 21:48
编译看左边,运行看右边。是成员函数在多态调用时的吧。 d.i是调用静态,静态是无论编译和运行都看引用型 ...
  1. class Super
  2. {
  3.     int i = 0;
  4.     public Super()
  5.     {
  6.         //System.out.println("B");
  7.         i+=2;
  8.     }
  9. }

  10. class Demo extends Super
  11. {
  12.     public Demo(String a)
  13.     {
  14.         //System.out.println("c");
  15.         i = 5;
  16.     }
  17.     public static void main(String[] args)
  18.     {
  19.         int i = 4;
  20.         Super d = new Demo("A");
  21.        // System.out.println(d.i);
  22.                
  23.                 Super d2 = new Demo("B");
  24.                 Super d3 = new Super();
  25.                 //System.out.println(d2.i);
  26.                
  27.                 d.i++;
  28.                 System.out.println(d.i);
  29.                 System.out.println(d2.i);
  30.                 System.out.println(d3.i);
  31.     }
复制代码


打印结果是
6
5
2
回复 使用道具 举报
我想 ,  Demo创建对象的时候, 就把i的值创建成了5, 存放到了堆内存.

d.i调用的就是此堆内存当中的i.而不是父类Super中的变量i.
回复 使用道具 举报
noiary 发表于 2014-8-26 22:03
我想 ,  Demo创建对象的时候, 就把i的值创建成了5, 存放到了堆内存.

d.i调用的就是此堆内存当中的i.而不 ...

我将函数改成:
  1. class Super
  2. {
  3.         int i = 0;
  4.         public Super()
  5.         {
  6.                 i+=2;
  7.         }
  8. }

  9. class Demo extends Super
  10. {
  11.          
  12.        
  13.         public Demo(String a)
  14.         {
  15.                 System.out.println("i="+i);
  16.                 i += 5;
  17.         }
  18.         public static void main(String[] args)
  19.         {
  20.                 int i = 4;
  21.                 Super d = new Demo("A");
  22.       
  23.                 System.out.println(d.i);
  24.                
  25.         }
  26. }
复制代码


结果是i=2    7
所以Demo构造函数对i的操作的确是用父类构造函数的结果来操作的。
回复 使用道具 举报

是的, 父类Super的成员变量i在栈内存,赋值为0;
创建子类对象后,子类对象运行Super构造函数,此时i被赋值为2;
紧接着输出子类构造函数Demo()中的 System.out.println("i="+i) 也就是 i = 2;
下面i又被赋值+5也就是2+5=7,我想这个i应该是在堆内存被创建的对象 new Demo() 当中,所以调用d.i 是7.

我想这时栈内存中的i应该还是7吧?  一会验证一下.
回复 使用道具 举报
本帖最后由 noiary 于 2014-8-27 09:09 编辑
  1. class Super
  2. {
  3.         int i = 0;
  4.         public Super()
  5.         {
  6.                 i+=2;
  7.         }
  8.                
  9.                 public int getI() {
  10.                
  11.                         return i;
  12.                 }
  13. }

  14. class Demo extends Super
  15. {
  16.          
  17.         
  18.         public Demo(String a)
  19.         {
  20.                 System.out.println("i="+i);
  21.                 i += 5;
  22.         }
  23.                
  24.                

  25.                
  26.         public static void main(String[] args)
  27.         {
  28.                 int i = 4;
  29.                 Super d = new Demo("A");
  30.                                 
  31.                 System.out.println(d.i);
  32.                                 d.i++;
  33.                 System.out.println("super.i= " + d.getI());
  34.         }
  35. }
复制代码


结果是
i=2
7
super.i= 8

d.i 变化  super.i也会变化....
回头要重新看看老毕的视频了..
回复 使用道具 举报

嗯,我昨天弄明白了
从结果来看确实是符合多态成员变量中的特点:看引用变量所属的类。
其实就是Demo构造函数中的i+=5;中的i省略了super
  1. public Demo(String a)
  2.         {
  3.                 System.out.println("i="+i);
  4.                 super.i += 5;
  5.         }
复制代码


所以Demo构造函数对i的操作的确是用父类构造函数的结果来操作的。
d.i调用的是引用变量所属类的变量,所以值是7.

辛苦哥们了,加个好友,此贴终结。
回复 使用道具 举报
围观.路过
回复 使用道具 举报
我是过来学习的:lol
回复 使用道具 举报
LFW 中级黑马 2014-8-27 10:05:22
18#
class 动物{}   class猫 extends动物{   main{ 动物 d =new 猫(“鱼”) ;  sop(动物 d 吃什么?)   }}  
回复 使用道具 举报
貌似楼主没理清关系!望再好好想想!
回复 使用道具 举报
我想我也明白了.

创建对象Super d = new Demo();  先运行子类构造函数,子类构造函数内先运行super() 父类构造函数,  所以i被赋值为2,(此i在子类中,而非父类)
这时父类中无论是构造函数Super()  还是i , 应该没有任何动作,  有的只是在子类中的 i = 0;    i += 2;    i += 5 ; 所以d.i结果才会为7.



不知道我这样理解对不对,我想是对的..{:3_67:}
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马