| Gzu521.com我的学习网 |
|
四,彻底划清界限(继续分离subclassing和subtyping) 在第二节我们讨论了部分分离subclassing和subtyping的方法,即subclassing-implies-subtyping. 现今的许多面向对象语言,如Java, C#都是采用了这种技术。除此之外,还有一种进一步分离subclassing和subtyping的方法。这种被称作inheritance-is-not-subtyping的方法通过完全割裂subclassing和subtyping之间的联系而在更大程度上方便了代码的重用。 DTycjx=hNfUf$,t [ 本 资 料 来 源 于 贵 州 学 习 网 IT认证计算机软件水平考试 http://Www.gzU521.com ] DTycjx=hNfUf$,t 它的产生很大程度上是由于人们想要使用在反协变位置上的self类型 (如self类型的参数)。当然,增大继承的能力的代价是subsumption的灵活性降低了。当self类型出现在反协变的位置上时,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 is0cr4Vt#PpI6F.g?[ 此文转贴于我的学习网IT认证计算机软件水平考试 http://www.Gzu521.com]0cr4Vt#PpI6F.g? 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的类型是一个出现在反协变位置上的self类型。 注意,方法max有一个反协变的参数类型self, 并且它被从类maxclass继承到了minmaxclass. 很直观地,类maxclass对应着类型max;类minmaxclass对应着类型minmax. 为了精确地表示这种对应关系,我们必须针对包含使用self类型的成员的类重新定义objecttypeof,以便得到objecttypeof(maxclass) = max, objecttypeof(minmaxclass) = minmax。 为了使以上的等式成立,我们把类中的self类型映射到objecttype中的类型名称本身。我们同时让self类型在继承的时候特化。 在本例中,当我们映射minmaxclass的类型时,我们把继承来的max方法中的self类型映射到minmax类型。而对maxclass中max方法的self类型,我们使用max类型。 如此,我们可以得到,任何maxclass生成的对象,都具备max类型。而任何minmaxclass生成的对象都具备minmax类型。 虽然minmaxclass是maxclass的子类,但这里minmax却不是max的子类型(subtype). 举个例子,如果我们假设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; 根据我们对self类型的映射规则和基于结构的subtype规则,我们知道,objecttypeof(minmaxclass’) = minmax, 所以,对任何minmaxclass’生成的对象mm’ ,我们可以知道mm’ : minmax. 而如果minmax <: max成立,根据subsumption, 我们就能推出mm’ : max. 于是当我们调用mm’.max(m)的时候,m可以是任何max类型的对象。但是,当max的方法体调用other.min(self)的时候,如果这个other不具有min方法,这个方法就会失败。 由此可见,minmax <: max并不成立。 子类(subclass) 在使用反协变的self类型时就不再具有subtype的性质了。 五,对象协议 (object protocol) 从上一节的讨论,我们看到对使用反协变self类型的类,subclass不再是subtype了。这是一个令人失望的结果,毕竟很多激动人心的面向对象的优点是通过subtype, subsumption来实现的。 不过,幸运的是,虽然失去了subtype, 我们还是可以从中挖掘出来一些可以作为补偿的有用的东西的。只不过,不象subtype, 我们不能享受subsumption了。 下面就让我们来研究这种新的关系。 在第四节的minmax的例子中,subtype不再成立;简单地使用泛型,引入 objectoperator p[m <: max] is … end; 也似乎没有什么用。p[max]虽然成立,但p[minmax]却是不合法的,因为minmax <: max不成立。 但是,直观上看,任何支持minmax这种协议的对象,也支持max协议的 (虽然我们还不知道这个“协议”到底是个什么东西)。于是,似乎隐隐约约地又一个叫做“子协议”(subprotocol)的家伙在向我们招手了。 为了发现这个子协议的关系,让我们先定义两个type operator (还记得吗?就是作用在类型上的函数):-mQ*0dXh@z,=m[本_文_来_源_于_我_的_学_习_网IT认证计算机软件水平考试 http://Www.GZU521.Com ]-mQ*0dXh@z,=m 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吗?给定一个函数f, f(fixpoint(f)) = fixpoint(f) 而在我们这个子协议的type operator里,如果我们认为type operator是作用于类型的函数的话, 那么这个“什么”,就是“什么-protocol”函数的fixpoint啊! |
责任编辑:gzu521