2013-02-05 75 views
3

我有一個家族的類型,我想模塊化「豐富」使用mixins。例如:家庭多態性+混合?

trait Family { 
    self => 
    trait Dog { 
    def dogname:String 
    def owner:self.Person 
    } 
    trait Person { 
    def name:String 
    def pet:self.Dog 
    } 
} 

trait SerializableFamily extends Family { 
    trait Dog extends super.Dog { 
    def toSimpleString:String = "Dog(" + dogname + ")" 
    } 
    trait Person extends super.Person { 
    def toSimpleString:String = "Person(" + name + ") and his pet " + pet.toSimpleString 
    } 
} 

trait SerializableFamily2 extends Family { 
    trait Dog extends super.Dog { 
    def toLoudString:String = "Dog(" + dogname.toUpperCase + ")" 
    } 
    trait Person extends super.Person { 
    def toLoudString:String = "Person(" + name.toUpperCase + ") and his pet " + pet.toLoudString 
    } 
} 

但是,上述不起作用(斯卡拉2.9.1)。最後一個表達式無法編譯(pet.toSimpleString)。

這僅僅是一個隨機的策略,我挑選了幾個我想:自己打字,抽象類型,超[...]等

我希望能夠做這樣的事情,最終:

val family = new Family with SerializableFamily with TraversableFamily with FooFamily {} 

其中每個mixin爲家族中的一個或多個類型添加一組協作方法。

這是一個常見的模式,我已經看到使用隱式包裝器,基於模式匹配的訪問者等解決。但由於它只是一個常規mixin模式的遞歸應用程序,我不知道是否可能有一個更簡單的方法實現這一目標。

回答

5

在你的情況下,錯誤是意料之中的,因爲在混入DogPerson覆蓋DogPersonFamily,使self.Person仍然指向Family.Person

這可能是更接近你想要

trait Family { 
    // type DogType = Dog won't work because then two different mixins 
    // have incompatible DogType implementations 
    type DogType <: Dog 
    type PersonType <: Person 

    trait Dog { 
    def dogname:String 
    def owner:PersonType 
    } 
    trait Person { 
    def name:String 
    def pet:DogType 
    } 
} 

trait SerializableFamily extends Family { 
    type DogType <: Dog 
    type PersonType <: Person 

    trait Dog extends super.Dog { 
    def toSimpleString:String = "Dog(" + dogname + ")" 
    } 
    trait Person extends super.Person { 
    def toSimpleString:String = "Person(" + name + ") and his pet " + pet.toSimpleString 
    } 
} 

什麼但你有一個像

new Family with SerializableFamily with TraversableFamily with FooFamily { 
    type DogType = super[SerializableFamily].Dog with super[TraversableFamily].Dog with super[FooFamily].Dog 
} 
+0

這主要是什麼,我會拿出一些令人討厭的,但是這是不是真的什麼如果我理解正確,OP希望。他希望「Dog」和「Person」的所有版本在混合時刻疊加起來,我認爲這根本不可能。 –

+0

@RégisJean-Gilles查看最新版本。 –

+0

+1,因爲這可能是最接近的。但明確混合所有版本的特徵是相當冗長:( –