以子类作为参数类型的Scala重写方法
我有一个以子类作为参数类型的Scala重写方法,scala,design-patterns,overriding,Scala,Design Patterns,Overriding,我有一个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
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不重写任何内容
。
我必须手动匹配详细的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 => ... }
}
此方法在编译期间无法检查正确的类型。如何实现第一个实现?
是否有任何设计模式来处理此问题
类似的问题是您可以使用泛型类型参数执行此操作
trait A[T <: B] {
def fun1( t:T ):C
}
class X1 extends A[B1]{
override def fun1(b:B1):C1 = ...
}
trait A[T无法重写为更具体的类型。当为更具体的类型创建其他方法时,可以重载(删除重写)。将根据传递的实际参数调用最具体的方法
class X1 extends A{
def fun1(b:B1):C1 = ...
}
在这种情况下,传递B1执行X1中的fun1,传递任何其他B执行a中的fun1
允许这种类型的重写实际上会阻止X1将B作为参数,只接受B1。这与Trait a声明和定义的方法直接冲突,无法重写它。如果允许重写,则X1.fun1(B:B)是不确定的。无法优化继承方法的参数类型,因为方法/函数在它们上面是逆变的
考虑这个简化的例子:
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)
这不会编译,但让我们先假设它会编译。如果我们需要迭代列表
,并通过foo
将动物
传递给每个实例,会发生什么情况?X1
应该能够处理任何动物
,但它只接受猫
,如果使用Dog
?你要求X1
打破与a
的契约,泛型是一种选择,但是fun1将只处理更具体的类型,而不是抽象类型(除非在trait中也定义了),你也可以使用抽象类型。trait a{type T最好使用单位
以外的返回类型,因为在这种情况下有一种合理的答案:什么都不做。