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

