java继承中的初始化顺序及方法调用

先上代码: 

package newcode;

public class granpa {
	public static int age;
	public int level;
	public granpa() {
		age=80;
		level=3;
		System.out.println("爷爷的构造函数");
		System.out.println("level="+level+",age="+age);
	}
	static {
		System.out.println("爷爷的静态块");
		System.out.println(",age="+age);
	}
	{
		System.out.println("爷爷的构造块");
		System.out.println("level="+level+",age="+age);
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}

}
package newcode;

public class dad extends granpa {
	public static int age;
	public int level;
	public dad() {
		level=2;
		age=50;
		System.out.println("爸爸的构造函数");
		System.out.println("level="+level+",age="+age);
	}
	static {
		System.out.println("爸爸的静态块");
		System.out.println(",age="+age);
	}
	{
		System.out.println("爸爸的构造块");
		System.out.println("level="+level+",age="+age);
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}

}
package newcode;

public class me extends dad{
	public static int age;
	public int level;
	public me() {
		level=1;
		age=20;
		System.out.println("我的构造函数");
		System.out.println("level="+level+",age="+age);
	}
	static {
		System.out.println("我的静态块");
		System.out.println(",age="+age);
		
	}
	{
		System.out.println("level="+level+",age="+age);
		System.out.println("我的构造块");
	}

	public static void main(String[] args) {
		new me();
		// TODO Auto-generated method stub

	}

}

 结果:

爷爷的静态块
,age=0
爸爸的静态块
,age=0
我的静态块
,age=0
爷爷的构造块
level=0,age=0
爷爷的构造函数
level=3,age=80
爸爸的构造块
level=0,age=0
爸爸的构造函数
level=2,age=50
我的构造块
level=0,age=0
我的构造函数
level=1,age=20

 总结:

  1. 首先初始化父类的静态成员变量和静态代码块,按照在程序中出现的顺序初始化
  2. 然后初始化子类的静态成员变量和静态代码块,按照在程序中出现的顺序初始化
  3. 其次初始化父类的普通成员变量和代码块,再执行父类的构造方法
  4. 最后初始化子类的普通成员变量和代码块,再执行子类的构造方法
  5. 还有注意:granpa g=new me();左边为编译,右边为运行。
  6. 用this()可以再构造器中调用构造器

再举一个例子,牛客中的一道题:

package newcode;

public class Test {
	static class A{
		protected int value;
		public A(int v) {
			setValue(v);
		}
		public void setValue(int value) {
			this.value=value;
		}
		public int getValue() {
			try {
				value++;
				return value;
			}
			catch(Exception e) {
				System.out.println(e.toString());
			}
			finally {
				this.setValue(value);
				System.out.println(value);
			}
			return value;
		}
	}
	static class B extends A{
		public B() {
			super(5);
			setValue(getValue()-3);
		}
		public void setValue(int value) {
			super.setValue(2*value);
		}
	}

	public static void main(String[] args) {
		System.out.println(new B().getValue());
		// TODO Auto-generated method stub

	}

}

输出结果:

22
34
17

题中注意要点:

  1. 有finally模块时,try{ }中已经return了,所以这个方法的返回值级已经保存下来了,题中是11,即使finally{ }里面又对value的值做出了改变,变成22,但是getValue()的返回值是不会变的。
  2. 注意运行时,先调用近的方法,没有再到父类中找,如果要指定调用父类的某个方法,要有super.method()来调用。

猜你喜欢

转载自blog.csdn.net/qq_33605294/article/details/87826442