亚型重写的方法的自变量[复制]

问题描述 投票:-2回答:1

这个问题已经在这里有一个答案:

下面的代码不编译。为什么我不能在SomeTypeString通过在SomeInst重载方法的参数?

trait SomeType
abstract class SomeClass[T] {
  def method(someType: SomeType): Unit
}
class SomeTypeString extends SomeType

class SomeInst extends SomeClass[String]() {
  override def method(someType: SomeTypeString): Unit = ???
}
scala
1个回答
4
投票

超类型的实例必须是由子类型的实例可更换,而不改变节目的期望的性质。这就是“亚型”使用里氏替换原则,这给子类型的行为基于合同的概念,需要走样考虑的非常清晰。

这意味着,无论我有SomeClass的实例,我也可以用SomeInst的一个实例。然而,在你的例子是不正确的:如果我有i的实例SomeClass然后我可以叫i.method(s),其中sSomeType的一个实例。按照里氏替换原则,我必须能够做同样的,当我打电话ii.method(s),其中iiSomeType的一个实例。但我不允许。我只允许通过SomeTypeString的一个实例。

人机工程学,你的榜样违反了里氏替换原则,或者,换句话说,SomeInst不允许是SomeClass的一个亚型。

请注意,这其实不是新的。这已经在之前就芭芭拉里氏制定了LSP上世纪60年代著名,这些只是对功能的标准分型的规则:

  • 功能逆变他们的参数类型
  • 功能是协变在它们的返回类型
© www.soinside.com 2019 - 2024. All rights reserved.