Scala - 为什么无法覆盖超类的方法

che*_*hry 3 scala

  class A
  class B extends A

  class D { def get: A = ??? }
  class E extends D { override def get: B = ??? } // OK

  class F { def set(b: B): Unit = ??? }
  class G extends F { override def set(a: A): Unit = ??? } // Compile Error, override nothing
Run Code Online (Sandbox Code Playgroud)

我的问题是为什么G不起作用,因为:(A => Unit)是(B => Unit)的子类型

implicitly[(A => Unit) <:< (B => Unit)]
Run Code Online (Sandbox Code Playgroud)

rse*_*nna 5

原因很简单:JVM不允许基于参数类型的逆变进行覆盖.它只允许基于返回类型协方差的覆盖.

看看这里有关它对Scala的影响的一些讨论.

来自维基百科:

类似地,允许覆盖方法接受比基类中的方法更通用的参数是类型安全的:

例如:

class AnimalShelter {
    void putAnimal(Animal animal) {
        ...
    }
}

class CatShelter extends AnimalShelter {
    void putAnimal(Object animal) {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

实际上没有多少面向对象的语言允许这样做--C++和Java [以及Scala]会将此解释为一个带有重载名称的无关方法.