天天看點

《面向對象的思考過程(原書第4版)》一1.9 繼承

面向對象程式設計的最強大的功能之一就是代碼重用。結構化設計提供的代碼重用非常受限。你可以編寫一個功能塊,然後多次重用它。但是面向對象的設計更進一步,允許你定義類之間的關系,通過組織和識别不同類之間的共性,不僅可以實作代碼重用,也可以指導設計。繼承是實作該功能的主要手段。

繼承允許一個類繼承另一個類的屬性和方法。我們可以通過抽象公共屬性和行為來建立新類。

面向對象程式設計中的一個主要設計問題就是識别多個類的共性。例如,假設你有一個dog(狗)類和一個cat(貓)類,這兩個類都有一個屬性來表示眼睛顔色。在過程化模型中,dog和cat的代碼中都會包含這個屬性。在面向對象的設計中,可以将顔色屬性上移到一個名為mammal(哺乳動物)的類中。該類也會包含一些其他的公共屬性和方法。在本例中,dog類和cat類都繼承自mammal類,如圖1-14所示。

《面向對象的思考過程(原書第4版)》一1.9 繼承

當dog或cat對象被執行個體化時,它包含了自身類的所有東西,也包含了從父類擷取到的東西。即dog擁有自身類定義的所有屬性,也包含了從mammal類繼承過來的屬性。

超類,也稱為父類(有時候也叫作基類),包含了繼承自它的所有類的公共屬性和行為。例如,在mammal類的例子中,所有的哺乳動物擁有相似的屬性,比如eyecolor和haircolor,也有相似的行為,比如generateinternalheat和growhair。所有的哺乳動物都有這樣的屬性和行為,是以沒必要在哺乳動物繼承樹中為每個動物中都重複一遍。重複不僅加重工作量,而且會帶來更多問題,因為會引入錯誤和沖突。

子類,也稱為孩子類(有時被叫作衍生類),是超類的擴充。比如,dog和cat類從mammal類繼承了所有的公共屬性和行為。mammal類是dog和cat子類的超類。

繼承提供了豐富的設計優勢。當設計cat類時,mammal類提供了很多需要的功能。通過繼承自mammal對象,cat已經擁有了成為真正的哺乳動物的所有屬性和行為。為了讓貓這種哺乳動物更加具體,cat類必須擁有貓自身獨一無二的屬性或行為。

繼承樹可能會增長的非常龐大。當mammal和cat類完成後,可以快速添加其他哺乳動物,比如狗(或者獅子、老虎和熊)。cat類也可以作為其他類的父類,比如作為塔羅貓等貓的父類。而dog類也可以作為germanshepherd(德國牧羊犬)和poodle(卷毛小狗)的父類(見圖1-15)。繼承的力量在于它的抽象群組織技術。

《面向對象的思考過程(原書第4版)》一1.9 繼承

在大多數最新的面向對象的語言中(比如java、.net和objective c),一個類隻能有一個父類,然而一個類可以有多個子類。另一些語言中,比如c++,可以擁有多個父類。前一種情況稱為單繼承,後一種情況稱為多重繼承。

請注意germanshepherd類和poodle類都繼承自dog類。每個類隻有一個方法。然而由于它們繼承自dog,是以它們也繼承自mammal。即germanshepherd和poodle類擷取了dog和mammal中所有的屬性和方法,同時也擁有它們自身的屬性和方法(如圖1-16所示)。

《面向對象的思考過程(原書第4版)》一1.9 繼承

在shape(形狀)例子中,circle(圓形)、square(矩形)和star(星形)都直接繼承自shape。這種關系通常被稱為is-a關系,因為圓是一個形狀,而矩形也是形狀。當子類繼承自父類時,任何父類能做的事情子類都可以做。即circle、square和star都是shape的擴充。

《面向對象的思考過程(原書第4版)》一1.9 繼承

在圖1-17中,每個對象上的名字draw分别代表了circle、star和square對象的draw方法。當我們設計shape系統時,采用這種方式對各種各樣的形狀進行标準化。這種方式非常有用,如果我們約定繪制形狀時隻需調用draw方法即可,而不用管具體是什麼形狀。那麼隻要遵守這一約定,無論什麼時候繪制形狀,隻需調用draw方法即可。這正好展示了多态的基本概念,即繪制circle、star或square是各自對象自身的職責。在如今很多軟體應用(比如在繪圖和文字處理應用)中都會使用多态概念。