軟件設(shè)計師知識點:面向?qū)ο笳Z言概論(四)

字號:

四,徹底劃清界限(繼續(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>