January 30 19:27~20:45
終於來到物件導向觀念介紹的最後一集inheritance(繼承),且看課本第57頁的定義:
If class B interits class A, then both the operations and the information structure described in class A will become part of class B.
接著課本解釋幾個與inheritance相關的名詞:
- Generalization:一般化,把好幾個不同的classes共同的特性抽離出來集中放到一個class中,然後讓原本的那些classes去繼承這個新的class。這種過程叫做generalization。感覺有點botton-up的方式來建構繼承架構。
- Specialization:特殊化,這個名詞一聽就知道跟generalization相反,也就是說假設鄉民們要新增一個class到現有的系統中,先找到一個既存的class其功能與資料和這個準備新增的class類似,然後讓這個準備新增的class去繼承原有的這個class,然後在這個新的class身上增加專屬於他自己的行為或資料。一個被特殊化的class其行為已經跟他的祖先不同了,換句話說,特殊化違反了Liskov Substitution Principle。
- Ancestors:祖先,在一個繼承架構中,某個class A之上的所有classes稱之為A的祖先。Ancestors又稱作superclasses(父類別)。。
- Descendants:後代,在一個繼承架構中,某個class A之下的所有classes稱之為A的後代。Descendants又稱作subclasses(子類別)。
- Direct descendant:直屬後代,直接繼承自某個class A的那個class稱之為class A的direct descendant或是child。
- Direct ancestor:直屬祖先,若class A為class B的direct descendant,則class B就稱為class A的direct ancestor或是parent。
- Abstract classes:祖先類別在設計的時候,其主要目的若是要讓其他類別繼承,則我們通常稱這樣的祖先類別為abstract classes。關於這一點雖然課本上這樣解釋,但是實務上我們會說一個無法產生instance的class就稱之為abstract class。
- Concrete class:和abstract classes相反,一個類別其設計之主要目的就是要讓人產生instance,則稱此類別為concrete class。實務上只要是能產生instance的類別都稱之為concrete classes。
***
這在邊Teddy先插花補充一的觀念,雖然在課本中並沒有提到,但是現在鄉民們可能都知道inheritance分成兩種:
- Implementation inheritance:實作繼承,子類別繼承父類別的介面以及實作。
- Interface inheritance:介面繼承,子類別只繼承父類別的介面。
接下來回到課本的內容,課本提到使用inheritance的四種時機:
- Reuse:透過implementation inheritance重複使用祖先類別中的行為與資料。剛開始學OO的人會認為reuse是使用繼承的主要目的,當年Teddy也是這樣認為,後來慢慢懂事之後,才發現如果光是為了reuse而使用繼承並不是一個好主意。且看GoF的Design Patterns第20頁告訴鄉民們:Favor object composition over class inheritance。
- Subtyping:一個類別(class)被視為某個型別(type)的實作就稱為subtyping(所以interface inheritance就是一種subtyping)。課本第64頁有講到一個重點:Subtyping normally occurs if the inheritance performs only an extension, rather than overriding something already defined in the ancestor.
- Specialization:前面已經解釋過,一個類別被特殊化之後,其行為已經跟他的祖先不相容了。有時候使用特殊化目的是因為後代類別與祖先類別大部分的行為都很相似,但是有少數幾個行為不同(可能後代增加新的行為,或是移除祖先的某些行為)。因為特殊化違反了Liskov Substitution Principle,所以使用特殊化的程式通常會看到instacne of 之類的判斷式(無法做polymorphism)。
- Conceptual:概念化,因為「概念上」某個類別屬於另外一種類別的後代,所以就使用了繼承。例如,人和狗都是一種動物,所以人和狗都繼承自動物這個類別。
這四種使用繼承的理由並非互斥的,例如,可能因為reuse的原因而套用subtyping或是specialization。根據課本的說法,subtyping是一種使用繼承比較好的理由。但是如果依據Design Patterns的說法:Favor object composition over class inheritance,吃飽沒事就不要用(實作)繼承了,但是介面繼承多用倒是無妨。
***
友藏內心獨白:今天中午吃得好飽。