簡體   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