Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop 类型-子类型关系。有些事情似乎不清楚_Oop_Liskov Substitution Principle - Fatal编程技术网

Oop 类型-子类型关系。有些事情似乎不清楚

Oop 类型-子类型关系。有些事情似乎不清楚,oop,liskov-substitution-principle,Oop,Liskov Substitution Principle,我正在阅读一些面向对象编程语言类的幻灯片,并进入了类型子类型定义: Barbara Liskov,“数据抽象和层次结构”,SIGPLAN注意到, 23,5(1988年5月): 这里需要的是一些东西 像下面的替换 属性:对于每个对象的 类型S有一个对象 键入T,使所有程序P 定义为T,即 当o_S为 代替o_T,则S为a T亚型 然后是一个例子: 点={x:Integer,y:Integer} PositivePoint={x:Positive,y:Positive} 其中正={k:Integer

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

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

这里需要的是一些东西 像下面的替换 属性:对于每个对象的 类型S有一个对象 键入T,使所有程序P
定义为T,即 当o_S为 代替o_T,则S为a T亚型

然后是一个例子:

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

我们能说那个正点吗≤ 要点

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

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

我怀疑语法是否是
类型≤ 子类型
或子类型≤ 键入,但语句似乎更清楚,那么怎么了


编辑 为了方便起见,问题是: 你能说
PositivePoint
点的一个子类型吗?
为什么?


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

假设程序必须绘制一个 从
点开始的方形地图
(-100,-100)
到
(100100)。你会怎么做 如果使用类型,则会发生这种情况
PositivePoint
?该计划是否有效 行为不变?不会的。 这种“不变的行为”是唯一的选择 我不明白的事。如果定义 子类型的类型是简单的
继承和
从其他类型覆盖它
可以,但似乎不行
这个案子


我还没看过电影≤ 这个符号以前用来表示这个,但我认为它的意思是
PositivePoint≤ 点
意味着
正点
具有更大的潜在值范围(即:
正点
的子集,
正点
的所有实例都可以被
的有效实例替换,但不是相反的方式)。

Liskov是正确的,正点≤ 点,因为正点是点的精化。任何使用Point的代码都必须能够使用PositivePoint,因为始终存在点坐标为正的可能性。反之则不然,因为使用PositivePoint的代码可能在坐标始终为正的假设下运行,而将PositivePoint替换为Point将打破该假设


请注意,她并不是说一个PositivePoint可以替换一个点,而是说一个PositivePoint可以在需要点的地方使用。

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

PositivePoint⊂ 点
与点
PositiveInt的原因相同⊂ Int
does:正数是所有可能数的子集


每个
PositivePoint
都属于
点,但不是相反。

思想是,任何接受PositivePoint的函数都依赖于点的值为正值这一事实。如果传入的点的值不是正值,则假设为false,函数将失败

但是,接受一个点的函数不会对该点的正性做出任何假设,因此,如果您传入了一个正性点,就可以了

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

编辑:详细说明:

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


然而,接受一个点的函数不知道该点的值是负值还是正值——它已经考虑到它们是正值的可能性。因此,传递一个正整数不能破坏任何东西。

她似乎说,如果你说正整数是点的一个子类型,:“当o_S代替o_t时,p的行为是不变的,那么S是t的一个子类型。”我一直认为“可能的正整数比点少”。所有可能的正点的集合都包含在所有可能点的集合中,因此比所有可能点的集合更大。@Dustman:这对我来说是有意义的,但是如果P是根据点定义的,并且你使用点定义的,我想让你再详细说明一下。对于我来说,
的范围更广,因此它可以用来代替
正点
,因为每个只使用正整数的操作都属于
的范围。不可变类是什么意思?如果你将程序设计为使用
它意味着它也可以使用负值,如果你用
正点
替换该类,那么“
P的行为保持不变
”是错误的,不是吗?@Andrea Ambu:如果P是