java--你可能忽略的细节(二)

类的继承:

初始化基础类

基础类子对象在构造器中正确地执行初始化操作,在衍生类的构造器中,java会自动插入对基础类的调用。

看以下代码:

package com.demo;

class Art{
	Art(){
		System.out.println("Art construct");
	}
}
class Drawing extends Art{
	Drawing(){
		System.out.println("Drawing construct");
	}
}

public class Cartoon extends Drawing {
	Cartoon(){
		System.out.println("Cartoon construct");
	}
	public static void main(String[] args) {
		Cartoon car= new Cartoon();
	}

}

输出为:Art construct

Drawing costruct

Cartoon construct

但是对于含有变量的构造器,就不能像上例一样默认的调用它们,因为不存在具体传递什么自变量的问题。所以必须明确编写关于对基础类的调用代码。这就是super关键字来实现的,看以下稍微改动的代码:

package com.demo;

class Art{
	Art(int i){
		System.out.println("Art construct"+i);
	}
}
class Drawing extends Art{
	Drawing(int i){
		super(i);
		System.out.println("Drawing construct"+i);
	}
}

public class Cartoon extends Drawing {
	Cartoon(){
		super(17);
		System.out.println("Cartoon construct");
	}
	public static void main(String[] args) {
		Cartoon car= new Cartoon();
	}
}

final关键字.

1,应用场合,数据:修饰基本数据类型的数据,该数据必须初始化而且之后的值不会变。如果是一个对象句柄来说的说,那么这个句柄初始化到某一个具体的对象,而且不能改变其指向另一个对象,但是对象的具体内容是可以修改的。

另外,若不是基本的数据类型,容许存在空白的final,(就是没有声明就初始化的)。

2,应用场合,方法:1,方法修饰为final,那么可以防止任何继承类改变它本来的含义。2,编译器对该方法的所有调用都置入“嵌入”调用里。只要编译器发现一个final方法调用,它会用方法主题内实际代码的一个副本来替代方法调用,这样做可避免方法调用时的系统开销。(备注:方法体积不能太大,应尽量精简)

3,应用场合,类:1,说明该类不允许被继承。2,对于final类,所以的方法都默认是final,其实,都没有子类,当然也就不会有重写类的情况发生,自然就是final的方法啦。


关于继承初始化

先看以下代码

package com.demo;

class Insect{
	int i=9;
	int j;
	Insect(){
		prt("i="+i+",j="+j);
		j=39;
	}
	
	static int x1=prt("static Insect.x1 initialized");
	
	static int prt(String s){
		
		System.out.println(s);
		return 47;
	}
}
public class Beetle extends Insect{

	int k = prt("Beetle.k initialized");
	
	Beetle(){
		prt("k="+k);
		prt("j="+j);
	}
	static int x2=prt("static Beetle.x2 initialized");
	
	static int prt(String s){
		System.out.println(s);
		return 63;
	}
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		prt("Beetle constructor");
		Beetle b = new Beetle();
	}
}


输出为:

static Insect.x1 initialized
static Beetle.x2 initialized
Beetle constructor
i=9,j=0
Beetle.k initialized
k=63
j=39

关于static,之前已经讲了很多了,就不多讲了。

注意两点1,在装载过程中,从父类开始(父类又有父类,就往上找),接下来根基础类初始化,再以此往下初始化,因为衍生类的初始化要依赖对基础类成员的正确初始化。

2,先载入(变量等)声明,再调用构造器,因为构造器往往是对相关的数据的初始化。











你可能感兴趣的:(java基础)