它對象的該方法保持不變。)
子類和繼承
子類和繼承(SubclassingandInheritance)子類和一般的類一樣,也是用來描述對象的結構的。但是,它是通過繼承其它類的結構來漸進式地實現這個目的。
父類的屬性會被隱式地複製到子類,子類也可以添加新的屬性。在一些語言中,子類甚至可以override父類的屬性(通過更改屬性的類型來實現)
父類中的方法可以被複製到子類,也可以被子類override.
一個子類的代碼的示例如下:
subclassreCellofcellis
varbackup:Integer:=0;
overrideset(n:Integer)is
self.backup:=self.s;
super.set(n);
end;
methodrestore()is
self.s:=self.backup;
end;
end;
對有subclass的方法解析,根據語言是靜態類型還是動態類型而有所不同。
在靜態類型的語言(如C++,Java)裡,父類,子類的methodsuite的拓撲結構在編譯時就已經確定,所以可以把父類的methodsuite裡的方法合並到子類的methodsuite中去,方法解析時就不用再搜索這個methodsuite的樹或圖了。(按:C++的vtable就是這種方法)
而對於動態類型的語言,(也就是說,父子類的關係是在運行時決定的),methodsuite就無法合並了。所以,方法解析時,就要沿著這個動態生成的樹或有向圖搜索直到找到合適的方法。而如果語言支持多繼承,這個搜索就更複雜了。
Subsumption和DynamicDispatch
從上述的幾個例子來看,似乎子類隻是用來從父類借用一些定義,以避免重複。但是,當考慮到subsumption,事情就有些不同了。什麼是Subsumption呢?請看下麵這個例子:
varmyCell:InstanceTypeOf(cell):=newcell;
varmyReCell:InstanceTypeOf(reCell):=newreCell;
proceduref(x:InstanceTypeOf(cell))is…end;
再看下麵這段代碼:
myCell:=myReCell;
本章節來源於𝑜𝑜𝑝.𝑡𝑤
f(myReCell);
在這兩行代碼中,頭一行把一個InstanceTypeOf(reCell)類型的變量賦值給一個InstanceTypeOf(cell)的變量。而第二行則用InstanceTypeOf(reCell)類型的變量作為參數傳遞給一個參數類型為InstanceTypeOf(cell)的函數。
這種用法在類似Pascal的語言中是不合法的。而在麵向對象的語言中,依據以下的規則,它則是完全正確的用法。該規則通常被叫做subtypepolimorphism,即子類型多態(按:其實subtyping應該是OO語言最區別於其它語言的地方了)
如果c’是c的子類,並且o’是c’的一個實例,那麼o’也是c的一個實例。
更嚴格地說:
如果c’是c的子類,並且o’:InstanceTypeOf(c’),那麼o’:InstanceTypeOf(c).
仔細分析上麵這條規則,可以在InstanceTypeOf的類型之間引入一個滿足自反和傳遞性的子類型關係,用<:符號來表示。(按:自反就是說,對任何a,a關係a都成立,比如說,數學裡的相等關係就是自反的。而傳遞性是說,如果a關係b,b關係c,就能推出a關係c。大於,小於等關係都是具備傳遞性的)
:則規條兩成拆被以可則規條這麵上麼那