Java的子类父类构造函数以及静态语句块加载

          最近在忙着找工作,之前也参加了阿里巴巴的校园招聘笔试,里面最后第二道题就是关于Java中构造函数、静态变量和静态语句块的加载问题。于是,小弟就自己就着Java的子类父类构造函数和静态语句块问题,去实践操作了一下,分享出来给大家看看。

一、Java的子类父类构造函数问题

       首先来看例子:

  • public class Child extends Father{
    
    	public Child(String s){
    		System.out.println("子类有参数");
    	}
    	
    	public Child(){
    		System.out.println("子类无参数");
    	}
    	    
    //      static{
    //              System.out.println("子类静态块");
    //      }
        
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		Child child = new Child("child_one");
    	}
    
    }
    
    class Father{
    	
    	public Father(){
    		System.out.println("父类无参数");
    	}
    	
    	public Father(String s){
    		System.out.println("父类有参数");
    	}	
    
    //     static{
    //              System.out.println("父类静态块");
    //    }
    
    }

运行结果:

父类无参数
子类有参数

        说明:在main方法中使用子类Child的含参构造函数去创建对象,而同时调用了父类Father的无参构造函数,并没有去调用含参的构造函数。

情况1:那如果把父类Father中的无参构造函数注释掉,为了表现说服力,把子类Child的无参构造函数也注释掉,此时就会报错了:

              Problem:未定义隐式超构造函数 Father()。必须显式调用另一个构造函数

         这也说明了之前提到的运行结果。

情况2:如果只想加载父类Father的含参构造函数,而不是无参构造函数,该怎么办?此时,super就发挥作用了,将子类Child的含参构造函数修改为:

	    public Child(String s){
		   super(s);         //必须第一行
		   System.out.println("子类有参数");
	    }
            再运行,运行结果为:

         父类有参数
         子类有参数

         顺便说一句,类自身的构造函数之间互相调用,使用this关键字。

二、Java静态语句块和构造函数的加载顺序

        其实这方面不需要细说,因为静态部分是随着类的加载而加载,构造函数是随着对象的创建而加载。也就是说,若在main方法中只声明子类Child类型的变量,静态部分会被执行,当然不会存在构造函数这一说了。接下来只是想通过子类Child继承父类Father的情况来展示静态块和构造函数的加载顺序。

        将文章开始的代码中的静态语句块部分消除注释,运行结果为:

        父类静态块
        子类静态块
        父类无参数
        子类有参数

        也就是说不管是父类还是子类的静态部分,都会在构造函数之前执行,它们是随着类的加载而加载。而父类肯定是先于子类加载,就像肯定先有猿,才有人一样。

你可能感兴趣的:(Java)