面向工具语言概论(一)
副标题#e#
本书是我们上面向工具范例理论的课本。其时上这门课时,心里满不觉得然,以为本身的 C++和OO已经颇有造纸,C++和Java的范例系统不说滚瓜烂熟,也是轻车熟路,上这么一门课 不是白拿学分?哈哈!
但一上起来,才发明本身竟如井底之蛙一样。老天,本来就这 么简朴的面向工具竟有这么多说道!本来除了C++, Java, 面向工具尚有这么多没见过头至没 想过的对象!
前几章概论,委曲还都搞定了。但后头上到范例系统的建模,subject reduction的证明,就发明本身就象回到了本科时代,这,这,这怎么都是数学啊!
这两天心血来潮。就想把它翻译一下。后头深邃的处所自觉功力太浅,就不蚍蜉撼树了。不 过,倒可以把前面几章的概论翻译一下,假如能起到辅佐各人开阔眼界的浸染,也就没白搭 劲。
第二章,基于类的面向工具语言
基于类的面向工具语言是面向工具世界 里的主流。它包罗:
Simula, 第一个面向工具语言
Smalltalk, 第一个支持动 态范例的语言
C++, 它的大部门基于类的特性担任自Simula.
等等等等。
与基于类的语言相对应的是基于工具的面向工具语言。这里“基于工具” 的观念和把Visual Basic叫做基于工具的观念是差异的。这里的“基于工具”是 指一个只以工具为中心,没有类的观念的语言,雷同Python之类的语言。
此刻,我们 来先容一下基于类的面向工具语言的一些配合特征。
1.类和工具
让我们先看 一个类的界说:
class cell is
var contents: Integer :=0;
method get(): Integer is
return self.contents;
end;
method set(n:Integer) is
self.contents := n;
end;
end;
一个类是用来描写所有属于这个类的工具的配合布局的。这个cell类表 示的工具拥有一个叫做contents的整数属性(attribute),这个属性被初始化成0。它还描写 了两个操纵contents的要领。Get和set. 这两个要领的内容都是很直观的。Self变量暗示这 个工具本身。
#p#副标题#e#
工具的动态语义可以这样领略:
一个工具在内部被暗示为一个 指向一组属性的指针。任何对这个工具的操纵城市颠末这个指针操纵工具的属性和要领。而 当工具被赋值或被看成参数通报的时候,所通报的只是指针,这样一来,同一组属性就可以 被共享。
(注, 有些语言如C++, 明晰区分指向属性组的指针和属性组自己,而一些 其它的语言则埋没了这种区别)
工具可以用new从一个类中实例化。精确地说,new C 分派了一组属性,
并返回指向这组属性的指针。这组属性被赋予了初始值,并包罗了 类C所界说的要领的代码。
下面我们来思量范例。对一个new C所生成的工具,我们把 它的范例记为InstanceTypeOf(c). 一个例子是:
var myCell: InstanceTypeOf(cell) := new cell;
这里,通过引入InstanceTypeOf (cell), 我们开始把class和type区分隔来了。我们也可以把cell自己看成是范例,但接下来 ,你就会发明,那样做会导致夹杂的。
2.要领理会。(Method Lookup)
给出 一个要领的挪用o.m(……), 一个由各个语言本身实现的叫做要领理会的进程负 责找到正确的要领的代码。(译者按:是不是想起了vtable了?)。
直观地看,要领 的代码可以被嵌入各个单个工具中,并且,对付很多面向工具语言,对属性和要领的相似的 语法,也确实给人这种印象。
不外,思量到节减空间,很少有语言这样实现。较量普 遍的要领是,语言会生成很多method suite, 而这些method suite可以被同一个类的工具们 所共享。要领理会进程会延着工具内指向method suite的指针找到要领。
在思量到继 承的环境,要领理会会越发巨大化。Method suite也许会被构成一个树,而对一个要领的解 析也许要查找一系列method suite. 而假如有多担任的话,method suite甚至大概构成有向 图,可能是环。
要领理会大概产生在编译时,也大概产生在运行时。
在一些 语言中,要领到底是嵌入工具中的,照旧存在于method suite中这种细节,对措施员是无关 紧急的。因为,所有能区分这两种模式的语言特性一般在基于类的面向工具语言中都不被支 持。
好比说,要领并不能象属性一样从工具中取出来看成函数利用。要领也不能象属 性一样在工具中被更新。(也就是说,你更新了一个工具的要领,而同一个类的其它工具的该 要领保持稳定。)
3. 子类和担任 (Subclassing and Inheritance)
子类和 一般的类一样,也是用来描写工具的布局的。可是,它是通过担任其它类的布局来渐进式地 实现这个目标。
父类的属性会被隐式地复制到子类,子类也可以添加新的属性。在一 些语言中,子类甚至可以override父类的属性(通过变动属性的范例来实现)
父类中 的要领可以被复制到子类,也可以被子类override.
一个子类的代码的示譬喻下:
#p#分页标题#e#
subclass reCell of cell is
var backup: Integer := 0;
override set(n: Integer) is
self.backup := self.contents;
super.set(n);
end;
method restore() is
self.contents := self.backup;
end;
end;
对有subclass的要领理会,按照语言是静态范例照旧动态范例而有所不 同。
在静态范例的语言(如C++, Java)里,父类,子类的method suite的拓扑布局 在编译时就已经确定,所以可以把父类的method suite里的要领归并到子类的method suite 中去,要领理会时就不消再搜索这个method suite的树或图了。(译者按:C++的vtable就是 这种要领)
而对付动态范例的语言,(也就是说,父子类的干系是在运行时抉择的) ,method suite就无法归并了。所以,要领理会时,就要沿着这个动态生成的树或有向图搜 索直到找到符合的要领。而假如语言支持多担任,这个搜索就更巨大了。