[英]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
并通过foo
将Animal
传递给每个实例,会发生什么? 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.