在Java中類複用有倆種情況,一是類的組合,二是類的繼承。組合是指在新類中使用已經產生的類的對象,也就是新類是由現有類對象的組合而成的,此種方法只是複用了現有程序的功能,而非它的形式。繼承無需改變現有類的形式,採用現有類的形式並在其中添加新代碼。但是在實際開發中並不是只要其中的一種,基本上是混合使用或者只用其中的一種,至於哪種複用方式更合適還需要根據具體的需求進行合理選擇。
一、組合
在組合時無需做一些特殊標記的,當在一個類中創建了另一個類的對象時,組合也就開始了。另外,每一個非基本類型的對象都有一個toString()方法,而且當編譯器需要一個String而你卻只有一個對象時,該方法便會被調用,實例如下:
class ZuHe{
private String s;
ZuHe(){
s="Hello!";
}
public String toString(){ //非基本類型的toString方法
return s;
}
}
public class TestZuHe{
private ZuHe zh=new ZuHe();
public String toString(){return "ZuHe=" + zh;}
public static void main(String[] args){
TestZuHe t = new TestZuHe();
System.out.print(t);
}
}
out:Hello
二、繼承
繼承(關鍵字super表示超類)需要在新類中用extends進行標記,一旦做了這個標記新類就會擁有基類所有的域和方法。在繼承中,當我們創建了一個子類對象時,該對象實際已經包含了一個基類的子對象。這個子對象與我們創建的基類對象是一樣的,唯一區別是後者來自於外部,而子對象被包裝在子類對象內部。關於這層關係可以從下邊的實例中看到,通過例子的輸出順序可以看出繼承關係的初始化過程是從上而下進行的:
class A{
public A(){
System.out.println("This is A");
}
}
class B extends A{ //A的子類
public B(){
System.out.println("This is B")
}
}
class C extends B{ //B的子類
public C(){
System.out.println("This is C")
}
public static void main(String[] args){
C c=new C(); //由於繼承關係:此時的對象c中包含着B的子對象,而B的子對象中包含着A的子對象
}
}
out:
This is A
This is B
This is C
上邊的例子實際也包含了基類的初始化,但是如果每個類中的構造器中包含參數又該如何進行初始化呢,此時就需要在子類構造器中通過super()進行參數傳遞,實例如下:
class A{
public A(int i){
System.out.println("This is A");
}
}
class B extends A{ //A的子類
public B(int i){
super(i);//通過此操作將參數i傳遞到A的構造器中
System.out.println("This is B")
}
}
class C extends B{ //B的子類
public C(){
super(11);//通過此方法將11傳遞到B的構造器中
System.out.println("This is C")
}
public static void main(String[] args){
C c=new C(); //由於繼承關係:此時的對象c中包含着B的子對象,而B的子對象中包含着A的子對象
}
}
另外,在繼承中還有一個叫做”向上轉型“的概念,向上轉型顧名思義就是子類向基類進行轉換,由於子類可以看作是基類的一個超集,因爲其既包含了基類中的所有方法,同時還擁有屬於自己的方法,所以在向上轉型中不會丟失基類中的方法,當然也因此稱子類與基類爲同一類型,具體實現可見如下代碼:
class Instrument{
public void play(){}
//此處傳入的是一個本類的實例
static void tune(Instruments i){
i.play();
}
}
public Test extends Instrument{
public static void main(String[] args){
tune(new Test);//傳入的是子類的實例,此爲向上轉型
}
}
三、代理機制
在Java中雖然沒有明確支持代理,但是在實際開發中仍然會遇到,代理之所以會被使用到是因爲繼承中的一個不可避免的問題——那就是一旦繼承基類所有的方法都會暴露給子類,即使子類不想要也會迫不得已的擁有。此時代理就是一個很好的處理方法,因爲代理可以選擇基類的部分方法也可以全部,子類只需要通過代理就可以獲取到自己想要的那一部分,實例如下:
public class Father{
private int a;
private Stirng s;
void A(){}
void B(){}
void C(){}
void D(){}
}
class Proxy{
private String name;
private Father f=new Father();
public Proxy(String name){
this.name=name;
}
public void A(){f.A();}
public void B(){f.B();}
public void C(){f.C();}
public void D(){f.D();}
}
class UseProxy{
public static void main(Stirng[] args)
{
Proxy p=new Proxy();
p.A();
p.B();
}
}
以上就是Java中最重要的類複用,通過這三種方式可以提高Java代碼的複用率,這樣可以大大節省開發時間,提高開發效率。但是在實際使用中也要根據需要做出合適的選擇,對於組合一定是最常用的,但是繼承卻要做到儘量不用或者慎重使用,就如Java編程思想中所說,”如果經過分析發現確實需要進行向上轉型,則繼承一定是必要的,但如果不需要向上轉型則要好好考慮。“。