以下代码无法编译。为什么不能在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 = ???
}
答案 0 :(得分:4)
父类型的实例必须可以被子类型的实例替换,而无需更改程序的所需属性。这就是使用Liskov替代原理的“子类型”的定义,该定义给出了基于行为的基于合同的子类型概念,其中考虑了混叠。
这意味着在任何地方我都有一个SomeClass
的实例,我也可以使用SomeInst
的一个实例。但是,在您的示例中,这是不正确的:如果我有i
的实例SomeClass
,那么我可以调用i.method(s)
,其中s
是{{1}的实例}。根据《里斯科夫替代原则》,我
当我打电话给SomeType
时,必须能够做到相同,其中ii.method(s)
是ii
的实例。但是我不被允许。我只允许传递SomeType
的实例。
Ergo,您的示例违反了Liskov替换原则,换句话说,不允许SomeTypeString
是SomeInst
的子类型。
请注意,这实际上并不新鲜。这在1960年代就已经知道,甚至在Barbara Liskov制定LSP之前,这些只是功能的标准子类型化规则: