黑马程序员技术交流社区

标题: 涉及到继承,的一个问题望解决 [打印本页]

作者: 高浩    时间: 2013-1-11 20:14
标题: 涉及到继承,的一个问题望解决
本帖最后由 张向辉 于 2013-1-16 12:30 编辑

class fu
{
       int shu=4;
          {
                   System.out.println(shu);

           }
         public fu ()
                {
                     System.out.println("haha");
                  }
}

class zi extends fu
{
          {  System.out.println(++num);          }
              int num=10;
           public  zi()
                {
                        System.out.println(++num);
                }
              public void  show()
               {
                        System.out.println(++num);

               }

}

public static void main(String []args)
{
                zi z=new zi();
                  z.show();
}

问下它的结果会是什么?但要告诉一下我它执行过程?
作者: 黑马王振宇    时间: 2013-1-11 20:16
结果是编译错误。看不懂、、、
作者: Rancho_Gump    时间: 2013-1-11 20:24
{  System.out.println(++num);          }
              int num=10;
这段会出现错误,应该将之调换位置
作者: 林嘉健    时间: 2013-1-11 20:53
同学 你写的代码挺别扭的。建议重新写一遍或者修改本帖

1.变量名最好取有意义的,最佳选择是用英文单词来定义一个变量。要真是不会再用拼音(坚决抵制拼音首字母拼出来的变量 例如:小狗 用Dog 绝对不要用XG)
2.别无缘无故的 用中括号 把代码括起来!  {  System.out.println(++num);          }     这句话我直接就郁闷了。
3.类里面定义的字段,建议加上修饰符。 别人一看就一目了然 了
作者: 胡勇敏    时间: 2013-1-11 20:56
本帖最后由 胡勇敏 于 2013-1-11 21:08 编辑

这里编译会报 "非法前向引用"的错误。错误出在你的非静态代码块{ System.out.println(++num); },这涉及到类的实例在创建时候的实例化过程,实际上,非静态代码块在类初始化创建实例时,将会被提取到类的构造器中,非静态(实例变量,非静态代码块)的地位是相等的,他们将按顺序被执行,而你的num定义在了{ System.out.println(++num); }后面,也就是你的非静态代码块在引用num的时候,num尚未被声明,你提前引用了它,所以才会报这样的错误。但是如果是静态代码块的话则可以向前引用。
子类和父类的执行顺序说明:

父类的静态初始化域,

子类的静态初始化域,

父类的非静态初始化域,

父类的构造函数,

子类的非静态初始化域,

子类的构造函数。

作者: 林其荣    时间: 2013-1-11 21:16
这段代码有两处错误:
第一缺少main方法的类
第二int num=10;应该定义在代码块前面,因为调用属性必须要先有属性
代码执行过程是:
先从执行main方法当创建子类对象zi z=new zi();因为
zi类有继承的父类所以就先初始化父类里面的语句而在java中代码块的执行优先构造函数所以
先执行代码块的语句再执行构造方法,所以在创建对象的时候先来初始化父类的代码块再初始化构造函数然后
再初始化子类的代码块和构造函数  
所以输出结果是:4  haha 11 12 13

而执行顺序是:
class fu//3 因为子类继承了父类所以先初始化父类
{
        int shu=4;
           {//4 代码块优先执行
                    System.out.println(shu);
      }
          public fu ()//5
                 {
                     System.out.println("haha");
                  }
}

class zi extends fu
{
          int num=10;
           { // 6初始化父类后再执行子类
                   System.out.println(++num);          }
                           public  zi()// 7
                 {
                         System.out.println(++num);
                 }
               public void  show()
                {
                         System.out.println(++num);
                }
}
class a{
        public static void main(String []args)//程序入口 1
        {
                 zi z=new zi();//2
                   z.show(); //8
        }
        }
作者: 林嘉健    时间: 2013-1-11 21:29
林嘉健 发表于 2013-1-11 20:53
同学 你写的代码挺别扭的。建议重新写一遍或者修改本帖

1.变量名最好取有意义的,最佳选择是用英文单词来 ...

我纯爷们啦

基础部分 面向对象语言都是一个道理吧?
作者: 张云杰    时间: 2013-1-11 22:04
本帖最后由 张云杰 于 2013-1-11 22:06 编辑

public class Test {

        private int num = 10;

        public Test() {
                System.out.println(++num); //这是父类的构造方法,也是先进行加减操作,然后打印输出
        }

        public void show() {
                System.out.println(++num);  //首先这里进行了++操作, 如果有方法调用的话, 这里要先加减然后输出
        }
}




public class Test1 extends Test {
        int num = 4 ;
        
         
    public void Test() {  //这个方法没调用
       System.out.println(num);
    }
   
        @Override
        public void show() {
                super.show(); //这个意思是说 调用父类里的show方法
                System.out.println(++num);
        }
        
        
    public static void main(String[] args) {
                Test1 test = new Test1(); //当子类重新new了, 那么首先它会去寻找父类的构造方法(死记),
                test.show();//接着调用了子类自己的方法;
                //总结下: 先是调用父类里的构造方法, 然后再调用子类自己的方法,子类重写父类的方法,默认调用子类方法, 因为子类里有个super方法,
                //super意思是说父类的意思, 调用了父类的方法,然后再执行打印 , 所以..如果程序是按照我这样写的话, 默认 答案应该是 11 ,12 ,5
                //++的意思是先加减,后执行操作;
        }
   
}






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