我们在编程过程中经常使用代码复用,其中主要有两种方式:组合与继承。
组合:即在编程中直接将某个类引入到新类中作为新类的field。
继承:子类继承了父类,就会自动获取到父类的field和方法(public和protected等)。
在学习的过程中发现了以下一个以前不曾注意的点:
①一个程序中含有多个类,每个类都可以具有自己的main方法,其他的类也可以相互调用main方法,看作普通的静态方法即可,而且更加方便进行测试。
②子类调用父类构造方法是,必须放在子类构造方法的起始位置。
③静态方法中不能使用非静态的成员变量或者方法。
这是由于使用static标注的field或者方法,表示其属于这个类,而非类的实例,而非静态的成员变量从属于类的实例,这样如果可以使用话,静态的方法并不会知道这些变量为哪个实例的变量,必然会出错。而且在静态方法中也不能使用 this 和 super。
④在子类重写父类方法时使用@Override标注该方法,可以防止误操为对父类方法的重载。
⑤组合与继承如何选择?
最简单的方法就是如果关系为"is-a"使用继承,"has-a"使用组合。
另一个判断的依据为:我们需不需要从子类向父类进行向上转型操作,如果必须向上转型则使用继承,否则不必使用。
⑥继承中类的初始化顺序
public class Beetle extends Insect {
private int k = printInit("Beetle.k initialized");
private String z;
public Beetle(int k, String z){
this.z = z;
this.k = k;
System.out.println("j = " + j);
System.out.println(z);
}
private static int x2 = printInit("staitc Beetle.x2 initialized");
public static void main(String[] args) {
System.out.println("Beetle constructor");
Beetle b = new Beetle(3,"Beetle.z");
}
}
class Insect{
private int i =9;
protected int j;
public Insect() {
System.out.println("i = " + i + ", j = " + j);
j = 39;
}
private static int x1 = printInit("static Insect.x initialized");
static int printInit(String s){
System.out.println(s);
return 47;
}
}
输出:
static Insect.x initialized
staitc Beetle.x2 initialized
Beetle constructor
i = 9, j = 0
Beetle.k initialized
j = 39
Beetle.z
java程序开始试图访问main方法,开始加载Beetle的编译代码,发现存在父类后,对父类进行加载,初始化(最先初始化static 的field)。然后对Beetle类建立对象
可以看出初始顺序:先对field进行初始化而后在执行构造方法。
⑦关于基类与子类
继承并不只是复制了基类的接口,当我们创建一个子类的对象时,该对象包含了一个基类的子对象(我想是super),这个子对象与直接使用基类创建的对象时一样的,只不过基类的子对象被包装在子类对象内部。