轉帖|其它|編輯:郝浩|2010-08-31 11:50:42.000|閱讀 698 次
概述:本文主要談談Java中的繼承與組合,希望帶大家有幫助。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
1.繼承和組合的概念
在新類里簡單地創建原有類的對象。我們把這種方法叫作“組合”,因為新類由現有類的對象合并而成。我們只是簡單地重復利用代碼的功能,而不是采用它的形式。
第二種方法是創建一個新類,將其作為現有類的一個“類型”。我們可以原樣采取現有類的形式,并在其中加入新代碼,同時不會對現有的類產生影響。這種魔術般的行為叫作“繼承”(Inheritance),涉及的大多數工作都是由編譯器完成的。對于面向對象的程序設計,“繼承”是最重要的基礎概念之一。對于組合和繼承這兩種方法,大多數語法和行為都是類似的(因為它們都要根據現有的類型生成新類型)。
2.組合也就是一個類的對象是另外一個類的成員,一般的程序都有組合的意味,只不過是基本數據類型是成員變量,下面請看具體的例子
class Head
{
Head(){
System.out.println(" head ");
}
}
class Body
{
Body(){
System.out.println(" body ");
}
}
class Person()
{
Head h=null;
Body b=null;
Person() //人是由頭和身體組成的,Head和Body的對象是Person的一部分
{
h=new Head();
b =new Body();
}
}
3.繼承作為面向對象的三個重要特性的一個方面,在面向對象的領域有著及其重要的作用,好像沒聽說哪個面向對象的語言不支持繼承
class Person
{
private String name=null;
private int age=0;
public Person(String n,int a)
{
name=n;
age=a;
}
int getAge()
{
return age;
}
String getName()
{
return name;
}
void getDescription()
{
System.out.println("name: "+name+"\t"+"age: "+age);
}
}
class Student extends Person
{
private String studno=null;
public Student(String n,String no,int a)
{
super(n,a);
studno=no;
}
}
說明:Student類中有三個成員變量name,age,studno和一個方法getDescription();
注意:子類繼承了父類的所有變量和函數,只是子類不能訪問父類的private類型的變量和函數,其實privae類型的變量還是繼承到子類中的
4.無論還是繼承,都允許我們將子對象置于自己的新類中。大家或許會奇怪兩者間的差異,以及到底該如何選擇。
如果想利用新類內部一個現有類的特性,而不想使用它的接口,通常應選擇組合。也就是說,我們可嵌入一個對象,使自己能用它實現新類的特性。但新類的用戶會看到我們已定義的接口,而不是來自嵌入對象的接口。考慮到這種效果,我們需在新類里嵌入現有類的private對象。
有些時候,我們想讓類用戶直接訪問新類的組合。也就是說,需要將成員對象的屬性變為public。成員對象會將自身隱藏起來,所以這是一種安全的做法。而且在用戶知道我們準備合成一系列組件時,接口就更容易理解。car(汽車)對象便是一個很好的例子:
class Engine {
public void start() {}
public void rev() {}
public void stop() {}
}
class Wheel {
public void inflate(int psi) {}
}
class Window {
public void rollup() {}
public void rolldown() {}
}
class Door {
public Window window = new Window();
public void open() {}
public void close() {}
}
public class Car {
public Engine engine = new Engine();
public Wheel[] wheel = new Wheel[4];
public Door left = new Door(),
right = new Door(); // 2-door
Car() {
for(int i = 0; i < 4; i++)
wheel[i] = new Wheel();
}
public static void main(String[] args) {
Car car = new Car();
car.left.window.rollup();
car.wheel[0].inflate(72);
}
} ///:~
由于汽車的裝配是故障分析時需要考慮的一項因素(并非只是基礎設計簡單的一部分),所以有助于客戶程序員理解如何使用類,而且類創建者的編程復雜程度也會大幅度降低。
如選擇繼承,就需要取得一個現成的類,并制作它的一個特殊版本。通常,這意味著我們準備使用一個常規用途的類,并根據特定的需求對其進行定制。只需稍加想象,就知道自己不能用一個車輛對象來組合一輛汽車——汽車并不“包含”車輛;相反,它“屬于”車輛的一種類別。“屬于”關系是用繼承來表達的,而“包含”關系是用組合來表達的。
5. protected
現在我們已理解了繼承的概念,protected這個關鍵字最后終于有了意義。在理想情況下,private成員隨時都是“私有”的,任何人不得訪問。但在實際應用中,經常想把某些東西深深地藏起來,但同時允許訪問衍生類的成員。protected關鍵字可幫助我們做到這一點。它的意思是“它本身是私有的,但可由從這個類繼承的任何東西或者同一個包內的其他任何東西訪問”。也就是說,Java中的protected會成為進入“友好”狀態。
我們采取的最好的做法是保持成員的private狀態——無論如何都應保留對基 礎的實施細節進行修改的權利。在這一前提下,可通過protected方法允許類的繼承者進行受到控制的訪問:
import java.util.*;
class Villain {
private int i;
protected int read() { return i; }
protected void set(int ii) { i = ii; }
public Villain(int ii) { i = ii; }
public int value(int m) { return m*i; }
}
public class Orc extends Villain {
private int j;
public Orc(int jj) { super(jj); j = jj; }
public void change(int x) { set(x); }
} ///:~
可以看到,change()擁有對set()的訪問權限,因為它的屬性是protected(受到保護的)。
6. 再論合成與繼承
在面向對象的程序設計中,創建和使用代碼最可能采取的一種做法是:將數據和方法統一封裝到一個類里,并且使用那個類的對象。有些時候,需通過“組合”技術用現成的類來構造新類。而繼承是最少見的一種做法。因此,盡管繼承在學習OOP的過程中得到了大量的強調,但并不意味著應該盡可能地到處使用它。相反,使用它時要特別慎重。只有在清楚知道繼承在所有方法中最有效的前提下,才可考慮它。為判斷自己到底應該選用組合還是繼承,一個最簡單的辦法就是考慮是否需要從新類上溯造型回基礎類。若必須上溯,就需要繼承。但如果不需要上溯造型,就應提醒自己防止繼承的濫用。
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉載自:網絡轉載