(强调我的)
但是,如果重新定义字段和函数类型共同导致没有问题,那么 为什么如何共同重新定义一个论证的类型会导致麻烦?
协变重新定义等于子类型,对吧?而且亚型可以取代他们的超类型!
捕获的是什么?
答案 0 :(得分:1)
问题不在于协方差本身。 (特别是,如果它是逆变型,那么按合同设计是不可能的,因为后代类特征中的参数类型不一定具有父母可用的特征。协方差不存在这样的问题。)< / p>
问题是协方差与多态性的结合。 E.g。
class A feature
foo (a: A) do a.bar end -- (1)
bar do end
end
class B inherit A redefine foo end feature
foo (a: B) do a.qux end -- (2)
qux do end
end
现在,以下代码将崩溃:
a: A; b: B
...
create b
a := b
a.foo (create {A})
实际上,a.foo
会调用版本(2),因为a
附加到B
类型的对象上。但是,传递给此功能的参数将为A
类型。并且A
没有导致运行时错误的功能qux
。这种错误称为CAT呼叫(更改可用性或类型)。
这个问题的解决方案是避免将协方差与多态性一起使用,即调用不应该是多态的,或者不应该对参数进行协变重新声明。关于这个解决方案的工作正在进行中。
答案 1 :(得分:0)
&#34;呼叫不应该是多态的,或者不应该有协变的重新声明。&#34;
你怎么知道?
让我们改变你的榜样:
嗡嗡声(a_a:A) 做 a_a.foo(创建{A}) 端这看起来很无辜。但是如果buzz收到动态类型B的参数,你仍然会得到嘘声。嗡嗡声的作者很可能处于B的存在未知的情况。
我认为你需要放弃&#34;呼叫不应该是多态的,或者#34;一点意见。只是禁止协变重新声明论点。