oop - 类型 - 子类型关系。似乎有些不清楚

标签 oop liskov-substitution-principle

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

Barbara Liskov,“数据抽象和层次结构”,SIGPLAN 通知,
23,5(1988 年 5 月):

What is wanted here is something like the following substitution property: If for each object o_s of type S there is an object o_T of type T such that for all programs P
defined in terms of T, the behavior of P is unchanged when o_S is substituted for o_T then S is a subtype of T



然后是一个例子:

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

Can we say that PositivePoint ≤ Point?

Yes, because an element of type PositivePoint may always replace an element of type Point in a program defined in Point terms!



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

我怀疑语法是否是 Type ≤ Sub-typeSub-Type ≤ Type ,但声明似乎更清楚,那有什么问题呢?

编辑

为了让事情更容易,问题是:
你能说PositivePointPoint 的子类型?
为什么?

第二次编辑

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

Suppose that the program has to draw a square map from Point (-100, -100) to Point (100, 100). What would happen if you use type PositivePoint? Would the program's behavior be unchanged? It would not. This "unchanged behavior" is the only thing I don't get. If the definition of subtype was simply inheriting and overriding from an other type it would be ok, but it doesn't seem to be the case.

最佳答案

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

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

关于oop - 类型 - 子类型关系。似乎有些不清楚,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2268018/

相关文章:

python - Mypy 在 __init__ 覆盖中接受不兼容的类型

oop - 替代(或改进)遭受 LSP 违规的状态模式

solid-principles - 该示例如何违反 LSP,进而导致违反 OCP?

java - 最佳实践是什么?

javascript - 创建自定义 JS 方法的正确方法

java - 如何有效控制实现多接口(interface)的类对象?

design-patterns - Liskov 替换原则是否也适用于实现接口(interface)的类?

oop - 从抽象类继承属性,并对抽象属性进行排序

java - 多线程、接口(interface)、扩展接口(interface)、面向对象的时尚跟踪与 Java 不起作用。我该如何解决它?

oop - 为什么 Rust 不支持特征对象向上转换?