四,徹底劃清界限(繼續(xù)分離Subclassing和Subtyping)
在第二節(jié)我們討論了部分分離Subclassing和subtyping的方法,即subclassing-implies-subtyping. 現(xiàn)今的許多面向?qū)ο笳Z言,如Java, C#都是采用了這種技術(shù)。除此之外,還有一種進一步分離Subclassing和subtyping的方法。這種被稱作inheritance-is-not-subtyping的方法通過完全割裂subclassing和subtyping之間的聯(lián)系而在更大程度上方便了代碼的重用。
它的產(chǎn)生很大程度上是由于人們想要使用在反協(xié)變位置上的Self類型 (如Self類型的參數(shù))。當(dāng)然,增大繼承的能力的代價是subsumption的靈活性降低了。當(dāng)Self類型出現(xiàn)在反協(xié)變的位置上時,subclass不再意味著subtype, 因此,subsumption也就不存在了。
下面請考慮這樣兩個類型:
ObjectType Max is
var n: Integer;
method max(other:Max): Max;
end;
ObjectType MinMax is
var n: Integer;
method max(other:MinMax): MinMax;
method min(other:MinMax): MinMax;
end;
再考慮兩個類:
class MaxClass is
var n:Integer :=0;
method max(other: Self): Self is
if self.n > other.n then return self else return other end;
end;
end;
subclass MinMaxClass of MaxClass is
method min(other: Self): Self is
if self.n < other.n then return self else return other end;
end;
end;
方法min和max是二元的,因為它操作兩個對象:self和other. other的類型是一個出現(xiàn)在反協(xié)變位置上的Self類型。
注意,方法max有一個反協(xié)變的參數(shù)類型Self, 并且它被從類MaxClass繼承到了MinMaxClass.
很直觀地,類MaxClass對應(yīng)著類型Max;類MinMaxClass對應(yīng)著類型MinMax. 為了精確地表示這種對應(yīng)關(guān)系,我們必須針對包含使用Self類型的成員的類重新定義ObjectTypeOf,以便得到ObjectTypeOf(MaxClass) = Max, ObjectTypeOf(MinMaxClass) = MinMax。
為了使以上的等式成立,我們把類中的Self類型映射到ObjectType中的類型名稱本身。我們同時讓Self類型在繼承的時候特化。
在本例中,當(dāng)我們映射MinMaxClass的類型時,我們把繼承來的max方法中的Self類型映射到MinMax類型。而對MaxClass中max方法的Self類型,我們使用Max類型。
如此,我們可以得到,任何MaxClass生成的對象,都具備Max類型。而任何MinMaxClass生成的對象都具備MinMax類型。
雖然MinMaxClass是MaxClass的子類,但這里MinMax卻不是Max的子類型(subtype).
舉個例子,如果我們假設(shè)subtype在這種情況下成立,那么,對以下的這個類:
subclass MinMaxClass’ of MinMaxClass is
override max(other: Self): Self is
if other.min(self) = other then return self else return other end;
end;
end;
根據(jù)我們對Self類型的映射規(guī)則和基于結(jié)構(gòu)的subtype規(guī)則,我們知道,ObjectTypeOf(MinMaxClass’) = MinMax, 所以,對任何MinMaxClass’生成的對象mm’ ,我們可以知道m(xù)m’ : MinMax.
而如果MinMax <: Max成立,根據(jù)subsumption, 我們就能推出mm’ : Max.
于是當(dāng)我們調(diào)用mm’.max(m)的時候,m可以是任何Max類型的對象。但是,當(dāng)max的方法體調(diào)用other.min(self)的時候,如果這個other不具有min方法,這個方法就會失敗。
由此可見,MinMax <: Max并不成立。
子類(subclass) 在使用反協(xié)變的Self類型時就不再具有subtype的性質(zhì)了。
五,對象協(xié)議 (Object Protocol)
從上一節(jié)的討論,我們看到對使用反協(xié)變Self類型的類,subclass不再是subtype了。這是一個令人失望的結(jié)果,畢竟很多激動人心的面向?qū)ο蟮膬?yōu)點是通過subtype, subsumption來實現(xiàn)的。
不過,幸運的是,雖然失去了subtype, 我們還是可以從中挖掘出來一些可以作為補償?shù)挠杏玫臇|西的。只不過,不象subtype, 我們不能享受subsumption了。
下面就讓我們來研究這種新的關(guān)系。
在第四節(jié)的MinMax的例子中,subtype不再成立;簡單地使用泛型,引入
ObjectOperator P[M <: Max] is … end; 也似乎沒有什么用。P[Max]雖然成立,但P[MinMax]卻是不合法的,因為MinMax <: Max不成立。
但是,直觀上看,任何支持MinMax這種協(xié)議的對象,也支持Max協(xié)議的 (雖然我們還不知道這個“協(xié)議”到底是個什么東西)。于是,似乎隱隱約約地又一個叫做“子協(xié)議”(subprotocol)的家伙在向我們招手了。
為了發(fā)現(xiàn)這個子協(xié)議的關(guān)系,讓我們先定義兩個type operator (還記得嗎?就是作用在類型上的函數(shù)):
ObjectOperator MaxProtocol[X] is
var n: Integer;
method max(other: X) :X;
end;
ObjectOperator MinMaxProtocol[X] is
var n:Integer;
method max(other: X):X;
method min(other: X):X;
end;
這樣,Max = MaxProtocol[Max], MinMax = MinMaxProtocol[MinMax]
更一般地說,我們可以定義:
什么 = 什么-Protocol[什么]
還記得lamda-calculus里的fixpoint嗎?給定一個函數(shù)F, F(fixpoint(F)) = fixpoint(F)
而在我們這個子協(xié)議的type operator里,如果我們認為type operator是作用于類型的函數(shù)的話, 那么這個“什么”,就是“什么-Protocol”函數(shù)的fixpoint?。?BR>
在第二節(jié)我們討論了部分分離Subclassing和subtyping的方法,即subclassing-implies-subtyping. 現(xiàn)今的許多面向?qū)ο笳Z言,如Java, C#都是采用了這種技術(shù)。除此之外,還有一種進一步分離Subclassing和subtyping的方法。這種被稱作inheritance-is-not-subtyping的方法通過完全割裂subclassing和subtyping之間的聯(lián)系而在更大程度上方便了代碼的重用。
它的產(chǎn)生很大程度上是由于人們想要使用在反協(xié)變位置上的Self類型 (如Self類型的參數(shù))。當(dāng)然,增大繼承的能力的代價是subsumption的靈活性降低了。當(dāng)Self類型出現(xiàn)在反協(xié)變的位置上時,subclass不再意味著subtype, 因此,subsumption也就不存在了。
下面請考慮這樣兩個類型:
ObjectType Max is
var n: Integer;
method max(other:Max): Max;
end;
ObjectType MinMax is
var n: Integer;
method max(other:MinMax): MinMax;
method min(other:MinMax): MinMax;
end;
再考慮兩個類:
class MaxClass is
var n:Integer :=0;
method max(other: Self): Self is
if self.n > other.n then return self else return other end;
end;
end;
subclass MinMaxClass of MaxClass is
method min(other: Self): Self is
if self.n < other.n then return self else return other end;
end;
end;
方法min和max是二元的,因為它操作兩個對象:self和other. other的類型是一個出現(xiàn)在反協(xié)變位置上的Self類型。
注意,方法max有一個反協(xié)變的參數(shù)類型Self, 并且它被從類MaxClass繼承到了MinMaxClass.
很直觀地,類MaxClass對應(yīng)著類型Max;類MinMaxClass對應(yīng)著類型MinMax. 為了精確地表示這種對應(yīng)關(guān)系,我們必須針對包含使用Self類型的成員的類重新定義ObjectTypeOf,以便得到ObjectTypeOf(MaxClass) = Max, ObjectTypeOf(MinMaxClass) = MinMax。
為了使以上的等式成立,我們把類中的Self類型映射到ObjectType中的類型名稱本身。我們同時讓Self類型在繼承的時候特化。
在本例中,當(dāng)我們映射MinMaxClass的類型時,我們把繼承來的max方法中的Self類型映射到MinMax類型。而對MaxClass中max方法的Self類型,我們使用Max類型。
如此,我們可以得到,任何MaxClass生成的對象,都具備Max類型。而任何MinMaxClass生成的對象都具備MinMax類型。
雖然MinMaxClass是MaxClass的子類,但這里MinMax卻不是Max的子類型(subtype).
舉個例子,如果我們假設(shè)subtype在這種情況下成立,那么,對以下的這個類:
subclass MinMaxClass’ of MinMaxClass is
override max(other: Self): Self is
if other.min(self) = other then return self else return other end;
end;
end;
根據(jù)我們對Self類型的映射規(guī)則和基于結(jié)構(gòu)的subtype規(guī)則,我們知道,ObjectTypeOf(MinMaxClass’) = MinMax, 所以,對任何MinMaxClass’生成的對象mm’ ,我們可以知道m(xù)m’ : MinMax.
而如果MinMax <: Max成立,根據(jù)subsumption, 我們就能推出mm’ : Max.
于是當(dāng)我們調(diào)用mm’.max(m)的時候,m可以是任何Max類型的對象。但是,當(dāng)max的方法體調(diào)用other.min(self)的時候,如果這個other不具有min方法,這個方法就會失敗。
由此可見,MinMax <: Max并不成立。
子類(subclass) 在使用反協(xié)變的Self類型時就不再具有subtype的性質(zhì)了。
五,對象協(xié)議 (Object Protocol)
從上一節(jié)的討論,我們看到對使用反協(xié)變Self類型的類,subclass不再是subtype了。這是一個令人失望的結(jié)果,畢竟很多激動人心的面向?qū)ο蟮膬?yōu)點是通過subtype, subsumption來實現(xiàn)的。
不過,幸運的是,雖然失去了subtype, 我們還是可以從中挖掘出來一些可以作為補償?shù)挠杏玫臇|西的。只不過,不象subtype, 我們不能享受subsumption了。
下面就讓我們來研究這種新的關(guān)系。
在第四節(jié)的MinMax的例子中,subtype不再成立;簡單地使用泛型,引入
ObjectOperator P[M <: Max] is … end; 也似乎沒有什么用。P[Max]雖然成立,但P[MinMax]卻是不合法的,因為MinMax <: Max不成立。
但是,直觀上看,任何支持MinMax這種協(xié)議的對象,也支持Max協(xié)議的 (雖然我們還不知道這個“協(xié)議”到底是個什么東西)。于是,似乎隱隱約約地又一個叫做“子協(xié)議”(subprotocol)的家伙在向我們招手了。
為了發(fā)現(xiàn)這個子協(xié)議的關(guān)系,讓我們先定義兩個type operator (還記得嗎?就是作用在類型上的函數(shù)):
ObjectOperator MaxProtocol[X] is
var n: Integer;
method max(other: X) :X;
end;
ObjectOperator MinMaxProtocol[X] is
var n:Integer;
method max(other: X):X;
method min(other: X):X;
end;
這樣,Max = MaxProtocol[Max], MinMax = MinMaxProtocol[MinMax]
更一般地說,我們可以定義:
什么 = 什么-Protocol[什么]
還記得lamda-calculus里的fixpoint嗎?給定一個函數(shù)F, F(fixpoint(F)) = fixpoint(F)
而在我們這個子協(xié)議的type operator里,如果我們認為type operator是作用于類型的函數(shù)的話, 那么這個“什么”,就是“什么-Protocol”函數(shù)的fixpoint?。?BR>