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)
原因很简单:JVM不允许基于参数类型的逆变进行覆盖.它只允许基于返回类型协方差的覆盖.
看看这里有关它对Scala的影响的一些讨论.
来自维基百科:
类似地,允许覆盖方法接受比基类中的方法更通用的参数是类型安全的:
例如:
Run Code Online (Sandbox Code Playgroud)class AnimalShelter { void putAnimal(Animal animal) { ... } } class CatShelter extends AnimalShelter { void putAnimal(Object animal) { ... } }实际上没有多少面向对象的语言允许这样做--C++和Java [以及Scala]会将此解释为一个带有重载名称的无关方法.