官术网_书友最值得收藏!

4.2 泛化關(guān)系

類與類之間的關(guān)系有多種,如依賴、實(shí)現(xiàn)和泛化等。泛化描述了一般事物與該事物的特殊種類之間的關(guān)系。在解決復(fù)雜問題時(shí),通常需要將具有共同特性的元素抽象成類,并通過增加其內(nèi)容而進(jìn)一步分類。例如,車可以分為火車、汽車、摩托車等。它們也可以表示為泛化關(guān)系,下面將詳細(xì)介紹與泛化相關(guān)的知識(shí)。

4.2.1 泛化的含義和用途

應(yīng)用程序中通常會(huì)包含大量緊密相關(guān)的類,如果一個(gè)類A的所有屬性和操作能被另一個(gè)類B所繼承,則類B不僅可以包含自己獨(dú)有的屬性和操作,而且可以包含類A中的屬性和操作,這種機(jī)制就是泛化(Generalization)。

UML中,繼承是泛化的關(guān)鍵。父類與子類各自代表不同的內(nèi)容,父類描述具有一般性的類型,而子類則描述該類型中的特殊類型。從另外一種方法來說,泛化是一種繼承關(guān)系,表示一般與特殊的關(guān)系,它指定了子類如何特化父類的所有特征和行為。例如,老虎是動(dòng)物的一種,既有老虎的特性,也有動(dòng)物的共性。

泛化關(guān)系是一種存在于一般元素和特殊元素之間的分類關(guān)系。這里的特殊元素不僅包含一般元素的特征,而且包含其獨(dú)有的特征。凡是可以使用一般元素的場(chǎng)合都可以用特殊元素的一個(gè)實(shí)例代替,反之則不行。

泛化關(guān)系只使用在類型上,而不用于具體的實(shí)例。泛化關(guān)系描述了“is a kind of”(是……的一種)的關(guān)系。例如,金絲猴、獼猴都是猴子的一種,東北虎是老虎的一種。在采用面向?qū)ο笏枷牒头椒ǖ牡胤剑话阍乇环Q為超類或者父類,而特殊元素被稱作子類。

UML規(guī)定,泛化關(guān)系用一個(gè)末端帶有空心三角形箭頭的直線表示,有箭頭的一端指向父類。如下圖演示了一個(gè)簡(jiǎn)單的泛化關(guān)系,其中Monkey類表示父類或超類,該類包含Golden Monkey和Macaque兩個(gè)子類,這兩個(gè)子類不僅繼承了父類中的所有屬性和操作,同時(shí)也可以擁有自己特定的屬性和操作。

泛化主要有兩個(gè)用途:第一個(gè)用途是,當(dāng)變量被聲明承載某個(gè)給定類的值時(shí),可使用類的實(shí)例作為值,這被稱作可替代性原則。該原則表明無論何時(shí)祖先被聲明了,其后代的一個(gè)實(shí)例都可以被使用。例如,如果猴子父類Monkey被聲明,那么一個(gè)金絲猴或者獼猴的對(duì)象就是一個(gè)合法的值。第二個(gè)用途是通過泛化使多態(tài)操作成為可能,即操作的實(shí)現(xiàn)是由它們所使用的對(duì)象的類決定的,而不是由調(diào)用者決定的。

4.2.2 泛化的層次與多重繼承

泛化可能跨越多個(gè)層次。一個(gè)子類的超類也可以是另一個(gè)超類的子類。如下圖所示為具體層次結(jié)構(gòu)的泛化。

在上圖中,AutoMobile類是Car類的子類,不僅如此,AutoMobile類還是PassengerCar類和TouringCar類的超類,這就顯示出了泛化的層次結(jié)構(gòu)。子類和超類這兩個(gè)術(shù)語是相對(duì)的,它們描述的是一個(gè)類在特定泛化關(guān)系中所扮演的角色,而不是類自身的內(nèi)在特性。在該圖中,Bicycle類表示Car類中的另外一個(gè)子類,也可以使用3個(gè)點(diǎn)表示省略號(hào),如果為3個(gè)點(diǎn)時(shí),表明Car類除了圖中所顯示的子類AutoMobile外,還可以擁有其他子類。

對(duì)泛化層次圖中的一個(gè)類而言,從它開始向上遍歷到根時(shí)經(jīng)歷的所有類都是其祖先,從它開始向下遍歷時(shí)遇到的所有類都是其后代。這里的“上”和“下”分別表示“更一般的類”和“更特殊的類”。

面向?qū)ο笤O(shè)計(jì)的最佳原則之一是避免緊密耦合的類,使一個(gè)類改變時(shí)不必改變一系列相關(guān)的其他類。由于泛化使用子類可以看見父類內(nèi)部的大部分內(nèi)容,使得子類緊密耦合于父類,所以泛化是類關(guān)系中最強(qiáng)的耦合形式。因此,使用泛化的基本原則是:只有在一個(gè)類確定是另外一個(gè)類的特殊類型時(shí)才使用泛化。

多重繼承在UML中的正式術(shù)語稱為多重泛化。多重泛化使同一個(gè)子類不僅可以像上圖中的Car類那樣具有多個(gè)子類,而且可以擁有多個(gè)父類,即一個(gè)類可以從多個(gè)父類派生而來。例如,坦克是一種武器,但它同時(shí)也可作為一種車來使用。多重泛化在UML中的表示方法如下圖所示。

在上圖中,一個(gè)子類帶有兩個(gè)指向超類的箭頭。通過Vehicle類的drive、reverse、park、start和stop操作確定了屬于Vehicle類的行駛功能,通過Weapon類的load、aim和fire操作確定了屬于Weapon類的破壞功能。ram和radio操作則是Tank類獨(dú)有的。

雖然UML支持多重泛化,但是通常情況下,實(shí)際應(yīng)用中的泛化使用并不多。其主要原因在于當(dāng)兩個(gè)父類具有重疊的屬性和操作時(shí),多重繼承里的父類會(huì)存在錯(cuò)綜復(fù)雜的問題。因此,多重繼承在面向?qū)ο蟮南到y(tǒng)開發(fā)中已經(jīng)被禁止,當(dāng)今流行的一些開發(fā)語言(如Java和C#)都不支持多重繼承。

4.2.3 泛化約束

泛化約束用于表明泛化有一個(gè)與其相關(guān)的約束,帶有約束條件的泛化也被稱為受限泛化。泛化建模約束有兩種情況:如果有多個(gè)泛化使用相同的約束,可以繪制虛線穿過兩個(gè)泛化,并且在花括號(hào)中標(biāo)注約束名;如果只有一個(gè)泛化,或者多個(gè)泛化共享關(guān)聯(lián)的空箭頭部分,就只需在朝向空箭頭的花括號(hào)中注明約束即可,如下圖所示。

泛化約束包含4種:不完全約束(Incomplete Constraint)、完全約束(Complete Constraint)、解體約束(Disjoint Constraint)和重疊約束(Overlapping Constraint)。

1.不完全約束

表示類圖中沒有完全顯示出泛化的類,這種約束可以讓讀者知道類圖中顯示的內(nèi)容僅僅是實(shí)際內(nèi)容的一部分,其余內(nèi)容可能位于其他類圖中,如下圖所示。

2.完全約束

與不完全約束相對(duì)應(yīng)的是完全約束,當(dāng)類圖中存在完全約束時(shí),表示類圖中顯示了全部?jī)?nèi)容,如下圖所示。

3.解體約束

表示緊靠約束下面的泛化類不能有子轉(zhuǎn)為通用的類,它比前兩種約束更加復(fù)雜,如下圖所示。

從上圖中可以看出,根超類OS有兩個(gè)子類Windows和Linux。解體約束表示W(wǎng)indows和Linux類都不能共享其他的子類。在該圖中,Windows類和Linux類都有各自的子類,但不能從Windows NT類到Linux類繪制一個(gè)泛化關(guān)聯(lián),由于解體約束的存在,Windows NT類不能同時(shí)繼承Windows和Linux類。

4.重疊約束

與解體約束作用相反的泛化約束,即重疊約束。該類型約束表示兩個(gè)子類可以共享相同的子類。如下圖所示,Database類有兩個(gè)子類Relational和OLAP,它們共享相同的類DataWarehouse。

主站蜘蛛池模板: 平谷区| 柳林县| 淮滨县| 阿坝县| 河西区| 阜新| 财经| 林周县| 沙坪坝区| 潼南县| 海门市| 昌黎县| 二手房| 正阳县| 六枝特区| 河南省| 阿巴嘎旗| 绥江县| 循化| 民勤县| 佛教| 分宜县| 故城县| 邵阳县| 峨眉山市| 巴彦县| 金寨县| 庄浪县| 鄂温| 沧州市| 江城| 松桃| 河津市| 饶平县| 丹棱县| 崇信县| 郁南县| 威海市| 长乐市| 青龙| 古丈县|