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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 孙飞 中级黑马   /  2012-7-23 17:05  /  2460 人查看  /  12 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 feigecal 于 2012-7-23 18:00 编辑

老师在视频中说的,在多态中,成员变量和静态函数的特点:无论编译和运行,都参考左边(引用型变量所属的类)。
那么为什么下面的小程序中的打印的 i 的值为5,不是要参考父类中的i 吗?
class Super
{
         int i=0;
         public Super(String a)
       {
                    System.out.println("A");
                      i=1;
         }
        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);
            }
}

12 个回复

倒序浏览
public Demo(String a)                                 
           {
                     System.out.println("C");
                      i=5;   
            }
相当于:
         public Demo(String a)                                 
           {
                      new Super();
                     System.out.println("C");
                      i=5;   
            }
貌似是这样。。。

}
回复 使用道具 举报
从main开始
1设置i=4
2Super d= new Demo(“a”) 先看Super中有带参数的构造方法没,因为子类继承父类,因为实际new的是子类的对象所以会运行子类的带参数的构造方法所以会输出c并且把i的值符上5.
回复 使用道具 举报
王贵朝 发表于 2012-7-23 17:20
从main开始
1设置i=4
2Super d= new Demo(“a”) 先看Super中有带参数的构造方法没,因为子类继承父类, ...

我的主要疑惑就是,子类构造函数中的赋值,赋的是父类中的 i  这一点,请详解一下
回复 使用道具 举报
杨文宇 发表于 2012-7-23 17:18
public Demo(String a)                                 
           {
                     System.out. ...

我的主要疑惑就是,子类构造函数中的赋值,赋的是父类中的 i  这一点,请详解一下
回复 使用道具 举报
因为这个子类构造函数里面的i是从父类那继承来的,i变成5后还是属于父类的,也就是父类的i变成了5,所以d.i里的i还是父类的i,输出当然是5了。
如果在子类里定义一个成员变量i,就是加上int i;这条语句,则子类构造函数里的i就不是父类里的i了,而是子类里面的i了,这时输出的d.i就是2了。
回复 使用道具 举报
http://bbs.itheima.com/thread-18693-1-1.html
这是我问的问题,希望能对你有帮助。
总结:编译看左边,运行看右边。{:soso_e113:}
我是笨的那种,就背下来了{:soso_e120:}
回复 使用道具 举报
孙飞 中级黑马 2012-7-23 17:55:28
8#
黑马-李勇 发表于 2012-7-23 17:51
http://bbs.itheima.com/thread-18693-1-1.html
这是我问的问题,希望能对你有帮助。
总结:编译看左边,运 ...

静态函数和变量的编译和运行都是看的左边
回复 使用道具 举报
class Super
{
         int i=0;
         public Super(String a)
       {
                    System.out.println("A");
                      i=1;
         }
        public Super()
        {
                  System.out.println("B");
                  i+=2;
        }
}
class Demo extends Super
{
            public Demo(String a)
            {          //Super()此处含有一隐式的父类构造函数 调用了Super类中的super构造方法
                     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);
            }
}
执行主函数中的i=4后 首先输出一个B 但要注意 此时的i和d均在栈内存的主函数中 然后执行下面的i+=2 注意 此时i在方法区中执行过后i=2 然后在执行输出C的语句 然后new Demo进堆内存 i的默认初始化值为0  通过i=5赋值语句将i值置为5 将a置为A 详细情况可以看我画的图 图中对象的地址值为自己随便赋的

无标题.png (22.64 KB, 下载次数: 65)

无标题.png
回复 使用道具 举报
段应腾 发表于 2012-7-23 18:21
class Super
{
         int i=0;

它最后打印的那个i是父类中的i。不是子类中的。这个题我差不多知道了,我感觉应该是,子类中构造函数的i 是从父类中那里继承来的,因为子类中并没有成员变量i。所以当new对象时存在于堆内存中的i虽然是存在于new子类对象时所以开辟的空间内,但因为是父类 的引用,所以给堆中的i赋的值是赋给了父类的成员变量,所以最后打印的是5。如果在子类的构造函数上面定义一个成员变量i,那么最后打印的将会是2.你回答的不太确定,我感觉你理解的也不是太正确,我的理解也只是勉强为了和答案一至吧,不太确定,希望你参考一下我的理解再补充一下,共同进步吧
回复 使用道具 举报
feigecal 发表于 2012-7-23 18:35
它最后打印的那个i是父类中的i。不是子类中的。这个题我差不多知道了,我感觉应该是,子类中构造函数的i  ...

首先、你要明白、当在堆内存中创建new Demo对象时、在堆内存中就有了成员变量a和i、只不过此时他们的值都是初始化的、这里i的初始化值为0 然后才被赋值为5 而开始执行的那个i+=2只是存在方法区中的i  最后在通过对象的调用去指向堆内存 中的i的 其实 画图最容易理解了......
回复 使用道具 举报
段应腾 发表于 2012-7-23 18:52
首先、你要明白、当在堆内存中创建new Demo对象时、在堆内存中就有了成员变量a和i、只不过此时他们的值都 ...

如果子类中也有一个成员变量i,那么是不是对象的内存中有两个变量i ?
回复 使用道具 举报
feigecal 发表于 2012-7-23 19:16
如果子类中也有一个成员变量i,那么是不是对象的内存中有两个变量i ?

  如果是局部变量i的话 会在栈内存中重新划分一片空间 出现一个i 、
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马