面向工具语言概论(四)
当前位置:以往代写 > C/C++ 教程 >面向工具语言概论(四)
2019-06-13

面向工具语言概论(四)

面向工具语言概论(四)

副标题#e#

四,彻底划清边界(继承疏散Subclassing和Subtyping)

在第二节我们接头了部门疏散Subclassing和subtyping的要领,即subclassing-implies-subtyping. 现今的很多面向工具语言,如Java, C#都是回收了这种技能。除此之外,尚有一种进一步疏散Subclassing和subtyping的要领。这种被称作inheritance-is-not-subtyping的要领通过完全盘据subclassing和subtyping之间的接洽而在更洪流平上利便了代码的重用。

它的发生很洪流平上是由于人们想要利用在反协变位置上的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 is

method min(other: Self): Self is

if self.n < other.n then return self else return other end;

end;

end;


#p#副标题#e#

要领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了。

#p#副标题#e#

下面就让我们来研究这种新的干系。

在第四节的MinMax的例子中,subtype不再创立;简朴地利用泛型,引入

ObjectOperator P[M <: Max] is … end; 也好像没有什么用。P[Max]固然创立,但P[MinMax]却是不正当的,因为MinMax <: Max不创立。

可是,直观上看,任何支持MinMax这种协议的工具,也支持Max协议的 (固然我们还不知道这个“协议”到底是个什么对象)。于是,好像隐隐约约地又一个叫做“子协议”(subprotocol)的家伙在向我们招手了。

为了发明这个子协议的干系,让我们先界说两个type operator (还记得吗?就是浸染在范例上的函数):

#p#分页标题#e#

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啊!

也就是说:

什么= fixpoint (什么-Protocol).

#p#副标题#e#

除了以上的fixpoint的性质,我们还发明白存在于Max和MinMax之间的干系。

首先,MinMax是MaxProtocol的一个post-fixpoint,即:

MinMax <: MaxProtocol[MinMax]

其次,我们可以看出:

MinMaxProtocol[Max] <: MaxProtocol[Max]

MinMaxProtocol[MinMax] <: MaxProtocol[MinMax]

最后,假如我们用<::来暗示一个更高阶的子范例干系:

P <:: P’ 当且仅当 P[T] <: P’[T] 

那么,MinMaxProtocol <:: MaxProtocol.

对付子协议的界说,我们可以采纳上面的<::的界说,即:

假如S-Protocol<::T-Protocol, 那么我们称范例S和范例T之间是子协议干系。 (1)

我们也可以不消这个高阶的干系,仍然利用<:这个subtype的干系:

假如S<:T-Protocol[S], 那么我们称范例S和范例T之间是子协议干系。 (2)

其实,第一个界说好像更直观一点,它更明晰地显示出子协议干系是浸染于范例上的函数(type operator)之间的干系,而不是范例之间的干系。

利用泛型技能,假如我们的某一个范例需要一个实现MaxProtocol的范例来实例化的话,我们可以回收下面两种要领中的一种:

ObjectOperator P1[X <: MaxProtocol[X]] is … end; (1)

ObjectOperator P2[P <:: MaxProtocol] is … end; (2)

这两种要领在表达本领上是沟通的。第一种要领叫做F-bounded parameterization. (译者按,Generic Java听说就回收了这个要领);第二种要领叫做 higher-order bounded parameterization.

对付详细语言的实现,为了利便,我们可以埋没这个type operator. 语法上可以直接对范例支持subprotocol的干系(用<#来暗示)。

对我们的MinMax的例子来说,我们就有:

MinMax <# Max.

(译者按,绕了一大圈,什么fixpoint啊,post-fixpoint啊,什么高阶干系啦,但愿没把你绕晕。其实,你只需要记着MinMax <# Max, 就八九不离十了,呵呵)

<#这个干系并不具有subsumption的性质,所以,你不能指望从它身上获得传统OO内里的多态。可是,与泛型相团结,它却长短常有用的。

好比说,我们可以对我们的所有你用来看成参数传给我的基于GP的快速排序模板函数给出这样的约束:用来实例化这个模板函数的的范例必需支持Comparable协议。

    关键字:

在线提交作业