组合与继承
1、 组合
组合:只需在新的类中产生现有类的对象。由于新的类由现有类的对象组成,所以称为组合。(只是复用了现有程序代码的功能,而非它的形式)如下:
class A{
private int a = 10;
private int b;
private float c;
}
public class B{
private String str;
private A a = new A();
pubblic String tostring(){
System.out.println("a");
}
}
2、 继承
继承:按照现有类的类型来创建新类。无需改变现有类的形式,采用往现有类的形式并在其中添加新代码。当创建一个类时,除非已明确指出要从其它类中继承,否则就是隐式地从Java的标准根类Object类进行继承。
注意:
1. 一个Java文件中可以含有多个类,但只能有一个public类。可以为每个类都创建一个public static void main(String []args){}方法。这样可以使得单元测试变得简便易行。
2. . 含有多个类,但只有(也只能有)一个public类的一个Java文件中。若所有类编译通过,此时执行 java className(非public类)命令,此时该类的main方法也会执行,即使这个类只有包访问权限,这个main方法也是可以执行的。
3. Java中用super关键字表示超类的意思(当前类就是从超类继承来的)。表达式super.method()表示将调用基类中的method()方法。
2.1、 初始化基类
对于不带参数的构造器及默认构造器:Java会自动在导出类的构造器中插入对基类构造器的调用。
带参数的构造器:如果没有默认的构造器或带参数的构造器,要使用基类导出类必须用super关键字显式的调用,并配以参数列表。
2.2、 向上转型
class Instrument{
public void play(){
}
static void tune(Instrument instrument){
//.....
}
}
public class Wind extends Instrument{
public sattic void main(String []args){
Wind wind = new Wind();
Instrument.tune(wind);
}
}
在上述代码过程中把Wind类型传入Instrument类型中,即由导出类转为基类(在继承图中是向上转型的,所以一般称为向上转型)。向上转型是从一个较专用类型向较通用类型转换,导出类可能比基类有更多的方法,但它必须至少含有基类的方法,所以在向上转型的过程中,类接口中唯一可能发生的方法就是丢失方法,所以总是很安全的。
2.3、 继承与初始化
类的代码在初次使用时才加载,通常发生于创建类的第一个对象之时,但是当访问static域或static方法时,也会发生加载。因为构造器也是static方法,只是没有显式的写出来,所以也可以说:“类是在任何static成员被访问时加载的”
初始化顺序:
首先:在对子类进行加载时,编译器发现子类有一个基类(由extends发现),则开始加载基类,若基类还有其自身的基类,则去加载其基类的基类。
然后,根基类中的static初始化,再下一个导出类中的static初始化,依次类推直到最后的一个导出类static也完成初始化。
至此所有类加载完毕,然后根基类的构造器被调用(无参构造器默认调用,有参数的则需用super指定调用)。在根基类构造器完成后,实例变量按次序被初始化,最后构造器的其余部分被执行。加粗这一部分需好好揣摩,实际上调用根构造器完成后可以理解为调用构造器只是通过构造器进入了被加载的当前类,并未执行构造器内部的其它语句,还得在按顺序将类中的实例变量初始化后,在进入构造器顺序执行其它语句。所以整体效果上来说,实例变量初始完成后,构造器才会执行其内的语句。
最后按上一步执行顺序对下一个导出类初始化,直到最后一个导出类初始完成。对象才算创建成功。
3、 继承与组合的区别
组合和继承都允许在新的类中放置子对象,组合是显式地这样做,而继承是隐式的做。
组合技术通常用于想在新类中使用现有类的功能而非它的接口这种情形。(has-a)"有一个"的关系是用组合来表示的。
在继承的时候,使用某个现有类,并开发它的一个特殊版本。这意味着你在使用一个通用类,并为了某种特殊需要而将其特殊化。(is-a)“是一个”的关系使用继承来表示的。
在讨论使用继承还是组合时,一个最清晰的判断就是是否需要进行从导出类到基类的向上转型,若必须向上转型则继承是必要的。