2013-02-05 6 views
3

믹스 인을 사용하여 모듈 식으로 "풍성하게"하고 싶은 패밀리 타입이 있습니다. 예 :가족 다형성 + 믹스 인?

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 패턴의 재귀 적 응용 프로그램이므로 더 간단한 방법이 있을지 궁금합니다. 를 성취하다. self.Person 여전히 Family.Person를 참조하도록

답변

5

은 귀하의 경우이 오류는, 유지 mixin에 DogPerson 이후 Family하지 재정DogPerson을 수행 예상된다.

이것은 당신이

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 이것은 아마도 당신이 얻을 수있는 가장 가까운 장소 일 것입니다. 그러나 명시 적으로 모든 버전의 특성을 혼합하는 것은 매우 장황합니다. –