繼承,是資料的延伸、是行為的改寫、是框架的客製化。在程式語言中,interface 可以是抽象的化身,也可以是物件的標籤。
在物件導向中,簡單的情境可以透過很直覺的手法化成資料結構,然而隨著時間演進情境越來越複雜,資料結構往往會開始跟著特例而越來越複雜。我們現在要處理集合論的抽象編寫[註 1]。
為了方便閱讀,我們使用 各式各樣的數 - wiki中的實數集合,並將所有的數字視為獨立的 Object。我們可以知道以下觀念:
實數(ℝ)包括有理數(ℚ),其中包括整數(ℤ),其中包括自然數(ℕ)
套用 Swift 的物件編寫方式,我們可以得到下面的程式碼:
// Swift
class ℝ {}
class ℚ: ℝ {}
class ℤ: ℚ {}
class ℕ: ℤ {}
基於這樣的故事,我們繼續來看看。
在 Object-Oriented Programming With ANSI-C 一書中,第 4 章節有提到,強烈建議讀者對這個 StackoverFlow 問題 有興趣可以看看。
// Objectiv-C
@interface R : NSObject
- (int) decimal;
@end
@interface Q : R
@end
@interface Z : Q
@end
@interface N : Z
@end
而在 Objective-C 的因為是屬於響應與否的程式設計,不像 Swift 必須要型別確定才可以順利執行。也由於這個關係,Objective-C 認為對 Object 呼叫不可響應的指令,是屬於 Design fault(程式設計錯誤),是需要我們自己調適的。
// Objective-C
R* r = [R alloc];
Q* q = [Q alloc];
Z* z = [Z alloc];
N* n = [N alloc];
[n isKindOfClass: [R class]]; // YES
[n isMemberOfClass: [R class]]; // NO
[n respondsToSelector: @selector(decimal)]; // YES