0

LSP

如果 q(x) 是关于 T 类型的对象 x 的可证明属性,那么 q(y) 应该对 S 类型的对象 y 为真,其中 S 是 T 的子类型。

我可以改写如下:

q(x) 对 T 的任何 x 为真 => q(y) 对 T 的任何子类型的任何 y 为真

现在另一个声明呢?

q(x) 对 T 的任何 x 都为真,并且 q(y) 对 S 的任何 y 都为真 => S 是 T 的子类型

是否有意义 ?我们可以用它作为 的定义subtype

4

3 回答 3

3
q(x) is true for any x of T and q(y) is true for any y of S => S is a subtype of T

答案是否定的。该表达式的意思是可以定义 S 和 T 的通用超类型 R,然后 LSP(对这个名称如何成为主流感到羞耻)将适用于 T->R 和 S->R。

在类型理论中,有一些类型,包括语义,并且有一些遵守语义的类型的实现,可能是通过继承实现。

在实践中,指定类型(q(x)部分)语义的唯一合理方法是通过实现,因此我们留下了接口形式的无语义签名,以及为实现目的而继承的,并实现接口他们喜欢,没有办法检查他们是否做得正确。

研究已经尝试定义形式语言来指定类型,因此工具可以检查实现是否遵守类型定义,但工作量太大,将形式语言编译成可执行代码也一样好。这是我认为永远无法解决的Catch-22问题。

回到你最初的问题,在允许今天所谓的“鸭子打字”的语言中,答案是不确定的,因为任何类型的对象都可以传递给任何函数,如果实现了正确的签名并且打字是正确的结果是对的。让我解释...

在像Eiffel这样的语言中,您可以在操作后必须增加的后置条件List.append()上放置。List.length()这不是 Perl、JavaScript、Python 甚至 Java 等语言的工作方式。与更严格的类型定义相比,缺乏类型严格性允许更简洁的代码。

于 2011-03-13T02:24:13.720 回答
2

它没有任何意义; 您使用的陈述and在 S 和 T 中是对称的。但我认为您的意思是说以下内容

如果对于任何命题 q 使得 q(x) 对于所有x类型都是可证明的T,那么 q(y) 对于所有类型 y:of 也是可证明的,那么S我们可以考虑S的子类型T

我更喜欢使用数理逻辑而不是非正式的英语,但如果我的定义正确,这就是行为子类型,现在通常被称为“鸭子类型”。这是一个非常好的子类型化原则,并且再次导致这样一种想法,即在任何期望 type 值的上下文中T,您可以改为提供 type 值S,这没关系,因为 type 的值S保证满足所有预期的属性上下文。

于 2011-03-13T03:38:38.847 回答
1

我认为不,您不能将其用作定义。此外,如果 q(x) 对 T 的任何 x 为真,并且 q(y) 对 S 的任何 y 都为真,这也可能意味着 T 是 S 的子类型。

要确定哪个是哪个子类型(假设您知道它们之间存在继承关系),您还必须知道哪个比另一个更“通用”或哪个更“专业”。

于 2011-03-11T11:05:01.127 回答