0

如何使此代碼有效?具有參數化功能的Scala動態調度

據我所知,Scala沒有動態調度(類似於Java)。是否有可能以某種方式模擬動態調度?

或者什麼是最好的解決方案?

object Tezt { 

    case class SuperClazz() 
    case class SubClazz1() extends SuperClazz 
    case class SubClazz2() extends SuperClazz 

    def method(obj: SubClazz1) = { 
    // stuff 
    } 

    def method(obj: SubClazz2) = { 
    // stuff 
    } 

    def func[T <: SuperClazz](obj: T) = { 
    Tezt.method(obj) // Error: Cannot resolve method reference with such signature 
    } 
} 
+0

java也不會允許這個。你的代碼完全錯誤。 嘗試解釋你正在試圖用文字去做什麼。 – Dima

+0

我說的Java也沒有。我有一個函數接收一個對象,它是'SuperClazz'的子類,並且有2個方法,每個子類都有onde。我如何知道要找到哪個? – pedrorijo91

+0

假設它被允許。如果你傳入一個Subclazz3的實例,那麼是什麼? – Dima

回答

4

上實現一個參數的動態調度的標準方法是面向對象的多態性

abstract class SuperClazz() { 
    def method(): ReturnType 
} 
case class SubClazz1() extends SuperClazz { 
    def method() = { 
    // stuff 
    } 
} 
case class SubClazz2() extends SuperClazz { 
    def method() = { 
    // stuff 
    } 
} 

// Alternatively just `def func(obj: SuperClazz) =` in this case 
def func[T <: SuperClazz](obj: T) = 
    obj.method() 

記住,你不能與其他case class延長case class,而且它通常被認爲是不好的風格完全可以擴展case class。爲了實現這個,你可能需要methodSuperClazz中是抽象的,因此SuperClazz應該是traitabstract class

在階動態調度另一種常見的方法是模式匹配:

sealed abstract class SuperClazz() 
case class SubClazz1() extends SuperClazz 
case class SubClazz2() extends SuperClazz 

def method(obj: SubClazz1) = { 
    // stuff 
} 

def method(obj: SubClazz2) = { 
    // stuff 
} 

def func(obj: SuperClazz) = 
    obj match { 
    case sc1: SubClazz1 => method(sc1) 
    case sc2: SubClazz2 => method(sc2) 
    } 

這是常見的實現方式類似這樣的匹配時,超類或性狀sealed(在這種情況下sealed abstract class SuperClazz())。在密封超類的對象上進行匹配時,編譯器會檢查你是否列出了匹配的所有可能性,以確保匹配時不會出現運行時錯誤。如果忘記指定一些可能性,編譯器會給你一個警告。

模式匹配也適用於多參數動態分派,但與多態性相比,它們通常需要編寫更多樣板代碼,並且可能會有更高的運行時性能成本,以便線性測試每個匹配案例並調用unapply函數。

+0

備註:我無法從另一個案例類擴展案例類?不知道,但我沒有得到任何錯誤。順便說一句,爲什麼被認爲是不好的做法來擴大案例類? – pedrorijo91

+1

@ pedrorijo91案例類從案例類繼承已被禁止自Scala版本2.9。你有沒有嘗試用這種繼承來編譯一些代碼? IDE可能不會出現錯誤,但它仍然不會在現代Scala版本中編譯。 – Kolmar

+1

@ pedrorijo91至於從案例類繼承正常的類,它往往只是沒有意義。所有自動案例類方法仍將由父案例類提供。例如,對孩子調用'copy'方法返回父類案例的一個實例。 unoverridden'equals'和'hashCode'只考慮父類案例中存在的字段。對於孩子來說,沒有自動伴侶對象使用'apply' /'unapply'。通常的方法是建立一些特徵和抽象類的層次結構,並且只在這個繼承層次結構中使葉子成爲'case class'es。 – Kolmar