子定型.PDFVIP

  • 2
  • 0
  • 约5.35万字
  • 约 22页
  • 2019-01-11 发布于天津
  • 举报
子定型

第 10 章 子定型 10.1 引 言 ` 本章考虑子定型(subtyping )和体现子定型在程序设计中作用的一些语言概念。简单地 讲,子定型是类型上的一种关系,该关系隐含一个类型的值可以代替另一个类型的值。和子 定型有关的一些语言构造是记录、对象和依赖于子类型关系的各种多态性等。本章的主要议 题如下: (1)带记录和子定型的简单类型化λ演算; (2 )相关的等式理论和语义模型; (3 )递归类型的子定型和对象的递归记录模型; 虽然对子定型的主要兴趣源于面向对象程序设计的普及,但是许多基本概念用更简单的 记录结构就很容易说明。 子定型出现在许多程序设计语言中。它最早出现在 Fortran 语言对“混合方式”算术的 处理中:算术表达式可以用整型和实型(浮点)表达式的混合写出,在需要时将整数转换为 实数。整数到实数的转换带有一些典型的子定型性质。特别是,在数学上通常把整数看成是 实数的一个子集。但是在程序中整数到实数的转换涉及到数据表示的变化,因此同记录或对 象的子定型相比,它不是典型的。Fortran 混合方式的算术还在两个方面超出了基本的子定 型。首先,Fortran 通过舍位提供了从实数到整数的隐式转换,但是舍位操作可能改变值。 其次 Fortran 还提供了重载运算,如+: int × int → int 和+: real × real → real 。如果忽略这两点 延伸,则可以把整型作为实型的子类型,该例对子定型的一般性质提供了一些直观概念。 子定型的另一个例子出现在 Pascal 的子界或与之密切相关的 Ada 的界约束中。包含整 数 1 到 10 的Pascal 子界[1..10]是整数的子区间。如果 x 是类型[1..10]的变量,并且y 是整型, 那么可以把 x 的值赋给y ,因为 1 到 10 之间的每个整数都是一个整型数。 更能体现功效的子定型例子出现在像 Eiffel 和 C++这样的类型化面向对象语言中。 在这 些语言中,一个对象类,暂时把它看成一种形式的类型,可以放置在一个子类型层级上。子 类型的对象可以用来代替任何超类型的对象,因为子类型关系保证所有需要的运算都被实 现。而且,虽然一个类型的对象的表示可能区别于一个子类型的对象的表示,但是这些表示 通常以某种方式相容,它避免了从一种类型到另一种类型转换。 通过比较程序设计语言的类型相等性和子定型,可以得出有关子定型的某种观点。在大 多数类型化程序设计语言中,某种形式的类型相等性用在类型检查中。类型相等性的一个基 本原则是,当两个类型相等时,若某表达式属于其中一个类型,则它同时也属于另一个类型。 有了子定型后,则用叫做“包容”(subsumption )的子定型性质来代替这个原则: 如果A 是 B 的子类型,那么类型A 的表达式也有类型B 。 这并不是完全恰当的子定型的定义,但是它对认识子定型是有帮助的。其中的主要概念是, 子定型是一种代替性质:如果A 是 B 的子类型,那么可以用A 的元素代替B 的元素。原则 上,如果可以有意义地用A 的元素代替B 的元素,那么把A 看成 B 的子类型是有意义的。 可以把记录类型作为一个简单的例子来说明。考虑记录类型 R 和 S ,其中类型R 的记录 有整型成员 a 和布尔型成员 b ,而类型S 的记录仅有整型成员a 。在 10.3 节的类型系统中, R 将是 S 的子类型。这是有意义的。要理解这一点,可以从在这两个类型的记录上都合法的 操作来考虑。因为每个 r:R 有成员 a 和 b ,因此表达式r.a 和 r.b 都是允许的。因为类型 S 的 记录仅有整型成员 a ,因此对每个s :S 来说,仅表达式 s.a 是合法的。比较这两个类型可以 1 看出,在类型 S 的元素上有意义的任何操作,在类型 R 的元素上也都有意义。于是,在包 含类型 S 的记录的任何表达式中,可以安全地使用类型 R

文档评论(0)

1亿VIP精品文档

相关文档