Liskov替换原则和数组不变性

时间:2013-04-18 21:51:26

标签: scala covariant

Liskov替换原则告诉我们,如果A是B的子类型,而不是我们可以用B类做的所有事情,那么我们应该可以使用类型A.

因此,为了进一步调查,我创建了以下内容:

class Animal

class Dog extends Animal

class BlueDog extends Dog

我明白为什么不允许这样做

val c: Array[Animal] = a

因为数组在Scala中不是协变的(就像它们在Java中一样)。

但是,我认为我应该能够做到:

  val a: Array[Dog] = Array(new Dog())
  val b: Array[BlueDog] = a

我希望val b没问题。 但我明白了:

class Array is invariant in type T. You may wish to investigate a wildcard type such as `_ >: ...

1 个答案:

答案 0 :(得分:1)

val a: Array[Dog] = Array(new Dog())
val b: Array[BlueDog] = a

有点奇怪,因为你的BlueDog比Dog更严格,可能有其他方法。

class Animal
class Dog extends Animal
class BlueDog extends Dog {
  def wolf() { println ("I'm a blue dog") }
}

那么下面的代码应该做什么?

val a: Array[Dog] = new Array(new Dog())
val b: Array[BlueDog] = a
b(0).wolf()

嗯,您的数组a中的狗没有wolf()方法....所以显然您不应该将父类型分配给子类型。

这就是为什么以下工作:

val dog: Dog = new BlueDog

但以下情况并非如此:

val blueDog: BlueDog = new Dog