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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

就是毕向东老师的一节练习视频。
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);
               
        }
}
这个程序运行后是BC5,BC我是知道的,但是我觉得d.i打印的结果应该是2.因为前面讲过:"在多态中,成员变量的特点:无论编译和运行,都参考左边(引用型变量所属的类),所以只应看左边d的引用类是父类Super.默认构造函数是空参数的,经过i+=2运算后应该是2啊。怎么会是5.于是我做了如下修改。
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
{
        int i = 3;
        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);
                Demo m = new Demo("B");
                System.out.println(m.i);
               
        }
}
这时候竟然变成2了,到底对于i的运算顺序是怎么样的?还有如果把我修改后的关于i 的分别加上//注释,会出现N多结果。我感觉很乱,求大神指教。

评分

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

查看全部评分

12 个回复

倒序浏览
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
{
        int i = 3;
        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);
                Demo m = new Demo("B");
                System.out.println(m.i);
        }
}
这种情况结果是2,5.字母我就不说了。
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
{
        //int i = 3;
        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);
                Demo m = new Demo("B");
                System.out.println(m.i);
               
        }
}
这种情况就变成了5,5.
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
{
        int i = 3;
        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);
                Demo m = new Demo("B");
                System.out.println(m.i);
               
        }
}
这种情况又变成了0,5.
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
{
        //int i = 3;
        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);
                Demo m = new Demo("B");
                System.out.println(m.i);
               
        }
}
这种情况又变成了2,2.
一下子弄出了好几种情况。到底内部的运行机制是什么啊?求高手指教啊。
回复 使用道具 举报
刚刚看了看,好像明白点了。请大神们帮我分析分析,看我说的对不对。
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
{
        //int i = 3;
        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);
                Demo m = new Demo("B");
                System.out.println(m.i);
               
        }
}//因为Demo继承Super所以,连int i=0继承了过来。i=5其实是改变了父类的i。所以父类的i也变成了5.

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
{
        int i = 3;
        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);
                Demo m = new Demo("B");
                System.out.println(m.i);
               
        }
}如果在Demo类中加入int i = 3;则是子类成员变量覆盖了父类中的i=0,这样子类,父类都有一个i,
但实质是不同的i,所以各司其职,这样上面父类的i最终会变成2,下面的子类i最终会变成5.  因而最终
d.i=2,  m.i=5
回复 使用道具 举报
本人QQ839007397
回复 使用道具 举报
  1. class Super
  2. {
  3.         int i = 0;
  4.         public Super(String a)
  5.         {
  6.                 System.out.println("A");
  7.                 i=1;
  8.         }
  9.         public Super()
  10.         {
  11.                 System.out.println("B");
  12.                 i+=2;
  13.         }
  14.         
  15. }
  16. class Demo1 extends Super
  17. {
  18.         int i = 3;
  19.         public Demo1(String a)
  20.         {
  21.                // super(a);//这样写才会调用父类有参数的构造函数,才会把父类的i设置为1.
  22.                 System.out.println("C");
  23.                 i=5;
  24.         }
  25.         public static void main(String[] args)
  26.         {
  27.                 int i = 4;
  28.                 Super d = new Demo1("A");
  29.                 System.out.println(d.i);//打印父类的属性i
  30.                                
  31.                 Demo1 m = new Demo1("B");
  32.                 System.out.println(m.i);//打印子类的属性i
  33.                
  34.         }
  35. }
  36. /*
  37. Super d = new Demo1("A");首先会去创建父类Super对象,
  38. Super你定义了两个构造函数,应该调用哪个了?此时你看子类构造函数了,子类构造函数中并没有调用有参数的父类构造函数
  39. 因此系统默认调用无参构造函数了,那什么情况下会调用父类构造函数了,当子类构造函数中有super(name)时
  40. 因此在初始化父类属性时,就打印了B 并设置了i为2,然后初始化子类对象时把子类的i设置成了5

  41. */
复制代码

评分

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

查看全部评分

回复 使用道具 举报
你发问题的时候 就是有变体的话 可以在一个代码中表示出来 我们自己会去看
回复 使用道具 举报
雅望天堂 发表于 2014-4-11 23:28
刚刚看了看,好像明白点了。请大神们帮我分析分析,看我说的对不对。
class Super
{

这个理解就差不多对了
回复 使用道具 举报
首先:成员变量是与所声明的类型(就是你说的左边)的成员变量绑定,这个没错。我们先看第一个情况i=5;这个i是super的i,demo把这个i继承下来,即super的i被赋值5 所以打印5.第二个情况,你注意你的demo重新定义了i=3,这时候在demo的构造函数里边的i=5是demo的 而父类super的i没有被改变所以仍然是2.
回复 使用道具 举报
雅望天堂 发表于 2014-4-11 23:28
刚刚看了看,好像明白点了。请大神们帮我分析分析,看我说的对不对。
class Super
{

对的 你明白的比我回复的早了一步 你可以看看我前面回复你的:lol
回复 使用道具 举报

  1. <P>class Super
  2. {
  3.         int i = 0;
  4.         public Super(String a)
  5.         {
  6.                 System.out.println("A");
  7.                 i=1;
  8.         }
  9.         public Super()
  10.         {
  11.                 System.out.println("B");//第【3】步:执行该语句,输出:B
  12.                 i+=2;//第【4】步:执行该语句,父类的i就为2;
  13.         }
  14.         
  15. }
  16. class Demo extends Super
  17. {
  18.         //int i = 3;//【说明】如果你在子类中定义了i,则i=5的语句是将5赋给了子类的i,则父类的i就是2了,也就是说对于变量,子类没有则</P>
  19. <P>                       //继承父类,子类有,则初始化的时候是改变了子类的变量。
  20.         public Demo(String a)
  21.         {
  22.                 //第【2】步:因为子类构造函数第一行有隐式的super();即先调用父类构造函数public Super()
  23.                 System.out.println("C");//第【5】步:父类相应构成函数初始化后,就回到了子类构造函数执行,输出:B
  24.                 i=5;//第【6】步:因为子类中没有定义i变量,所以子类就继承了父类的i,然后将5赋给了父类 i ;所以d.i输出的还是父类的i,即</P>
  25. <P>                      //变量行看左边是没有错的.
  26.         }
  27.         public static void main(String[] args)
  28.         {
  29.                 int i = 4;
  30.                 Super d = new Demo("A");//第【1】步:创建子类对象,调用子类构造函数public Demo(String a)

  31.                 System.out.println(d.i);
  32.                
  33.         }
  34. }
  35. </P>
复制代码

回复 使用道具 举报
caijunsong 发表于 2014-4-11 23:43
这个理解就差不多对了

谢谢师兄
回复 使用道具 举报
K.L.Zous 发表于 2014-4-11 23:53
对的 你明白的比我回复的早了一步 你可以看看我前面回复你的

谢谢师兄
回复 使用道具 举报
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马