一个例子理清java中的继承

public class TestExtends {
	public static void main(String[] args) {
		Son son1 = new Son();
	}
}

class Parent {
	private static int a = 1;
	static{//静态代码块
		System.out.println("a = "+a);
	}
	
	private int b = 2;
	{//动态代码块
		System.out.println("b = "+b);
	}
	
	public Parent(){
		System.out.println("---------parent----------");
	}
}

class Son extends Parent{
	private static int c = 1;
	static{
		System.out.println("c = "+c);
	}
	
	private int d = 2;
	{
		System.out.println("d = "+d);
	}
	
	public Son(){
                //super();默认调用,当父类只有有参的构造器时就要显示调用有参构造器才行,如super(c);
		System.out.println("---------------son-------------");
	}
}

输出结果:

a = 1

c = 1

b = 2

---------parent----------

d = 2

---------------son-------------

对于java继承中的价载顺序其实一直不是很了解,最近看了<thinking in java>里面的解释,发现大体是理顺了,所以记录一下,方便以后查看:

1,加载的时候先是类加载:就是说一个类要new对象,是要先把类加载进jvm的,一旦他发现了extends关键字的话,就会先去加载父类的类文件,一层一层的父类加载完了之后,最后才是子类本身;

加载类文件的同时,类变量(static)先加载,所以上面的例子输出结果如下:(为了输出结果用到了静态跟动态代码块,其实就把这两块东西当做静态变量跟成员变量理解就可以了,他们的最大作用是起到

变量的初始化而已)

a = 1

c = 1

2,经过了类加载一步后,开始要来新建对象了,在子类的构造器中是会默认先调用父类的构造器的,所以父类先建对象,也就是先加载父类的成员变量,然后再执行父类的构造器里面的内容,得到结果如下:

b = 2

---------parent----------

3,父类的对象新建完成,轮到子类的了,子类开始初始化成员变量,然后执行本身的构造器里面的内容,得到结果如下:

d = 2

---------------son-------------

PS:对于<thinking in java>中有一句话,很是疑惑,中文版P94页里面写到“无法阻止自动初始化的进行,它将在构造器被调用之前发生。。。”,当初因为这个还以为是先加载成员变量,再执行构造器里面的super(),结果是super先执行了。。。是我理解有问题?

猜你喜欢

转载自panshaobinsb.iteye.com/blog/2269755