这个问题已经在这里有一个答案:
下面的代码不编译。为什么我不能在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 = ???
}
超类型的实例必须是由子类型的实例可更换,而不改变节目的期望的性质。这就是“亚型”使用里氏替换原则,这给子类型的行为基于合同的概念,需要走样考虑的非常清晰。
这意味着,无论我有SomeClass
的实例,我也可以用SomeInst
的一个实例。然而,在你的例子是不正确的:如果我有i
的实例SomeClass
然后我可以叫i.method(s)
,其中s
是SomeType
的一个实例。按照里氏替换原则,我必须能够做同样的,当我打电话ii.method(s)
,其中ii
是SomeType
的一个实例。但我不允许。我只允许通过SomeTypeString
的一个实例。
人机工程学,你的榜样违反了里氏替换原则,或者,换句话说,SomeInst
不允许是SomeClass
的一个亚型。
请注意,这其实不是新的。这已经在之前就芭芭拉里氏制定了LSP上世纪60年代著名,这些只是对功能的标准分型的规则: