繁体   English   中英

Scala覆盖方法,子类为参数类型

[英]Scala override method with subclass as parameter type

我有一个trait A有一个方法def fun1( b:B ):C我想要A的子类工具B有更详细的类型:

这是代码:

trait B
trait C

trait A {
  def fun1( b:B ):C
}

class B1 extends B{
}

class B2 extends B{
}


class C1 extends C{
}

class C2 extends C{
}

我希望A的子类可以声明如下

class X1 extends A{
    override def fun1(b:B1):C1 = ...
}


class X2 extends A{
    override def fun1(b:B2):C2 = ...
}

但是,编译器会抱怨X1 overrides nothing 我必须手动匹配详细的B类型,如下所示。

class X1 extends A{
    override def fun1(b:B):C = b match {case x:B1 => ... }
}


class X2 extends A{
    override def fun1(b:B2):C2 = b match {case x:B2 => ... }
}

此方法无法在编译期间检查正确的类型。 我怎样才能实现第一次实施? 有没有设计模式来处理这个问题?

类似的问题是C#Override方法和子类参数

您可以使用泛型类型参数执行此操作。

trait A[T <: B] {
   def fun1( t:T ):C
}

class X1 extends A[B1]{
    override def fun1(b:B1):C1 = ...
}

您无法优化继承方法的参数类型,因为方法/函数对它们是逆变的。

考虑这个简化的例子:

trait A {
    def foo(b: Animal): Unit
}

trait Animal
class Cat extends Animal
class Dog extends Animal


class X1 extends A {
    def foo(b: Cat): Unit
}

class X2 extends A {
    def foo(b: Dog): Unit
} 

val list: List[A] = List(new X1, new X2)

这不会编译,但让我们暂时假装它。 如果我们需要遍历list并通过fooAnimal传递给每个实例,会发生什么? X1应该能够处理任何Animal ,但它只接受一只Cat ,当传递一只Dog时会发生什么? 你要求X1打破与A合同。

您无法覆盖更具体的类型。 在为更具体的类型创建其他方法时,您可以重载(删除覆盖)。 将根据传递的实际参数调用最具体的方法。

class X1 extends A{
  def fun1(b:B1):C1 = ...
}

在这种情况下,传递B1执行X1中的fun1,传递任何其他B执行在A中的fun1。

允许这种类型的覆盖基本上会阻止X1将B作为参数,仅接受B1。 这与Trait A声明和定义的方法直接冲突,无法覆盖它。 如果允许覆盖,则x1.fun1(b:B)是不确定的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM