[英]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.