黑马程序员技术交流社区

标题: 关于子父类中变量加载的问题 [打印本页]

作者: 李新辉    时间: 2013-11-4 16:22
标题: 关于子父类中变量加载的问题
本帖最后由 李新辉 于 2013-11-4 16:26 编辑

new Dome()这个对象为什么建立的是父类中的 “ i ” 呢??
主函数中定义的那个 “ i ” 呢??
函数不是先从主函数开始执行的吗?
Dome的对象中有几个 “ i ” 呢


我有点不太明白……

360截图20131104161126943.jpg (48.39 KB, 下载次数: 46)

360截图20131104161126943.jpg

作者: Mr.Z.Lee    时间: 2013-11-4 16:28
一个对象中的变量不可以重名,也就意味着该对象中的变量对应的值是唯一的,所以new Dome()只有一个i
作者: 从前有个人    时间: 2013-11-4 16:40
主函数里的那个i和对象不是完全没有关系么,那个i不是在栈里单独窝在角落中。
作者: 夕拾    时间: 2013-11-4 17:59
本帖最后由 夕拾 于 2013-11-4 18:01 编辑

该程序首先执行主函数,主函数第二行新建子类对象时,JVM默认先执行super();语句,这样子类就继承了父类的属性,子类中 i=5; 是赋值运算,并不是定义新的属性。
作者: 魏-玉-彪    时间: 2013-11-4 18:50
  1. class Super{
  2.         int i=0;
  3.         public Super (String a){
  4.                
  5.                 System.out.println("A");
  6.                
  7.                 i=1;
  8.         }
  9.         public Super(){    //第二步

  10.                 System.out.println("B");
  11.                 i+=2;
  12.         }
  13.        
  14. }


  15. class Dome extends Super {

  16.         public Dome (String a){               //第三步
  17.                 System.out.println("C");
  18.                 i=5;              //第四步  重新赋值
  19.                
  20.         }
  21.         public static void main(String[] args) {
  22.                 int i=4;   //初始化
  23.                 Super d=new Dome("A");          //第一步
  24.                 System.out.println(d.i);    //第五步  
  25. //而这里又是多态,d 是一个Super 对象,所以打印
  26. 中的Super i

  27.         }

  28. }
复制代码
程序的加载顺序:
1静态代码
2代码块
3构造函数 如有父类,先加载父类
4向下执行.






作者: Clare0621    时间: 2013-11-4 20:28
本帖最后由 Clare0621 于 2013-11-4 20:32 编辑

简单说下那个程序的运行步骤:
  1. class Super
  2. {
  3.         int i = 0; //i值赋为0,调用空参构造函数public Super()----------------------------------第四步
  4.         public Super(String a)
  5.         {
  6.                 i=1;
  7.         }
  8.         public Super()
  9.         {
  10.                 i += 2;// 执行到此,i值由0变为2,父类构造函数调用完毕,然后转入子类public Demo继续执行----第五步
  11.         }
  12. }
  13. class Demo extends Super
  14. {
  15.         public Demo (String a)
  16.         {
  17.                 //super();//关键在这:子类构造函数默认都有此语句用来调用父类构造函数,并且必须先执行,
  18.                 //程序调到父类构造函数public Super()执行-------------------------------------------------第三步
  19.                 i = 5;//将i赋值为5-------------------------------------------------------------------------第六步
  20.         }
  21.         public static void main(String[] args)
  22.         {
  23.                 int i = 4;//定义变量i并赋值为4--------------------------------------------------------------第一步
  24.                 Super d=new Demo("A");//多态——新建父类引用指向子类对象,调用子类构造函数public Demo---------------第二步
  25.                 System.out.println(d.i);//打印d的i值为5---------------------------------------------第七步
  26.         }

  27. }
复制代码

作者: 李新辉    时间: 2013-11-4 21:21
本帖最后由 李新辉 于 2013-11-4 21:23 编辑
Clare0621 发表于 2013-11-4 20:28
简单说下那个程序的运行步骤:

class Super
{
        int i = 0; //i值赋为0,调用空参构造函数public Super()----------------------------------第四步
        public Super(String a)//子类对象初始化调用父类空参数构造函数没有调用这里的    i    啊?
        {                               //如果这里是第四步,那么   i   在这里又再一次定义了,这样会编译失败的
                i=1;
        }
        public Super()
        {
                i += 2;// 执行到此,i值由0变为2,父类构造函数调用完毕,然后转入子类public Demo继续执行----第五步
        }
}
class Demo extends Super
{
        public Demo (String a)
        {
                //super();//关键在这:子类构造函数默认都有此语句用来调用父类构造函数,并且必须先执行,
                //程序调到父类构造函数public Super()执行-------------------------------------------------第三步
                i = 5;//将i赋值为5-------------------------------------------------------------------------第六步
        }
        public static void main(String[] args)
        {
                int i = 4;//定义变量i并赋值为4--------------------------------------------------------------第一步
                Super d=new Demo("A");//多态——新建父类引用指向子类对象,调用子类构造函数public Demo---------------第二步
                System.out.println(d.i);//打印d的i值为5---------------------------------------------第七步
        }

}


作者: 李新辉    时间: 2013-11-4 21:30
Clare0621 发表于 2013-11-4 20:28
简单说下那个程序的运行步骤:

你的回复 我倒是还算赞同
是不是子类对象初始化调用父类的空参数构造函数
而这个空参数的构造函数没有调用  父类中的定义的  i    呢?
而只是给  子类main函数的    i    重新赋值了呢?
作者: Clare0621    时间: 2013-11-4 23:22
本帖最后由 Clare0621 于 2013-11-4 23:28 编辑
李新辉 发表于 2013-11-4 21:30
你的回复 我倒是还算赞同
是不是子类对象初始化调用父类的空参数构造函数
而这个空参数的构造函数没有调 ...

其实最后打印的i是父类的属性i,这个例子里面子类主函数的int i=4,只是个局部变量,其实没用或者你在主函数里面运行System.out.println(i);直接打印i则会输出4,简而言之,主函数里面的i和父类以及子类构造函数里面的i根本不是同一回事,作用域都不一样,一个是成员变量,一个是局部变量,不影响。
另补充一下:如果在子类Demo里面在定义个成员变量:int i = 0;则子类构造函数里面的i就不会指向父类i,而是使用自己的变量i,那么打印d.i值就会是2而不是5了,这是多态里面,变量不呈现多态性的原因。

作者: Clare0621    时间: 2013-11-5 00:14
本帖最后由 Clare0621 于 2013-11-5 00:17 编辑

这个确实有点绕人。。。{:soso_e134:}




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