6

我正在阅读有关面向对象编程语言的课程的一些幻灯片,并进入了类型子类型定义:

Barbara Liskov,“Data Abstraction and Hierarchy”,SIGPLAN Notices,23,5(1988 年 5 月):

这里需要的是类似于下面的替换属性:如果对于每个 S 类型的对象 o_s 有一个 T 类型的对象 o_T 使得对于
根据 T 定义的所有程序 P,当 o_S 被替换时 P 的行为不变对于 o_T 则 S 是 T 的子类型

然后是一个例子:

Point = { x:Integer, y:Integer }
PositivePoint = { x:Positive, y:Positive }
其中Positive = { k:Integer | k > 0 }

我们可以说 PositivePoint ≤ Point 吗?

是的,因为PositivePoint 类型的元素可能总是替换Point 术语定义的程序中的Point 类型的元素!

现在......对我来说,它似乎应该完全相反:Point ≤ PositivePoint 因为我不能在使用负坐标的 Point 的程序中使用 PositivePoint,而我可以相反。

我怀疑语法是Type ≤ Sub-typeor Sub-Type ≤ Type,但语句似乎更清楚,那有什么问题?


编辑

只是为了让事情更容易,问题是:你能说那PositivePoint是 的子类型Point吗?为什么?


第二次编辑

我在这里报告我在评论中写的内容,希望它能让我的问题更清楚:

假设程序必须绘制一个从Point(-100, -100) 到Point(100, 100) 的正方形地图。如果你使用 type 会发生什么 PositivePoint?程序的行为会不会改变?它不会。这种“不变的行为”是我唯一没有得到的。如果子类型的定义只是inheriting and overriding来自其他类型,那没问题,但似乎并非如此。

4

4 回答 4

3

Liskov 是正确的,PositivePoint ≤ Point,因为 PositivePoint 是 Point 的细化。任何使用 Point 的代码也必须能够使用 PositivePoint,因为Point 的坐标总是有可能是正的。反之则不然,因为使用 PositivePoint 的代码可能会在坐标始终为正的假设下运行,而将 PositivePoint 替换为 Point 会破坏该假设。

请注意,她并不是说 PositivePoint 可以代替 Point,只是说 PositivePoint 可以在需要 Point 的地方使用。

于 2010-02-15T18:27:04.237 回答
1

您可以通过子集对类型关系进行建模。

PositivePoint ⊂ Point理由与此相同PositiveInt ⊂ Int:正数是所有可能数的子集!

每个都PositivePoint属于Points,但不属于其他方式。

于 2010-02-15T18:27:12.713 回答
1

这个想法是任何接受 PositivePoint 的函数都依赖于该点的值为正的事实。如果您传入一个值不是正数的点,则假设是错误的并且函数将失败。

然而,接受点的函数不会对点的积极性做出任何假设,所以如果你传入一个 PositivePoint,那就没问题了。

请注意,这仅适用于不可变的 Point 类。如果您能够更改 Point 的值,PositivePoint 和 Point 可能根本没有子类关系,因为p.x = -1PositivePoints 的操作将失败。

编辑:详细说明:

假设我们有一个二维数组,它会在需要时自动增长(即,当传递两个正索引时,您永远不会遇到索引越界错误)。现在我们有一个函数,它接受一个 PositiveInteger p,然后访问索引 x,y 处的二维数组。这不会失败,因为 x 和 y 保证为正数,并且二维数组可以使用任何一对正数索引进行索引。但是,如果 Point 是 PositivePoint 的子类型,则 p 实际上可能具有负值,即使它被声明为正值。这意味着使用它来索引数组不再安全。

但是,接受 Point 的函数不知道该点的值是负值还是正值 - 它已经考虑到它们是正值的可能性。所以传入 PositiveInteger 不能破坏任何东西。

于 2010-02-15T18:28:55.817 回答
0

我以前没有见过用于表示此的 ≤ 符号,但我认为这PositivePoint ≤ Point意味着它Point的潜在值范围大于PositivePoint(即:PositivePoint是 的子集Point,所有实例PositivePoint都可以替换为的有效实例Point,但不是相反。)

于 2010-02-15T18:24:55.420 回答