家族多态性+ Mixins?

Ald*_*chi 3 scala traits mixins

我有一个类型的家庭,我想用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
  }
}
Run Code Online (Sandbox Code Playgroud)

但是,上述方法不起作用(Scala 2.9.1).最后一个表达式无法编译(pet.toSimpleString).

这只是我从几个尝试过的随机策略:自我打字,抽象类型,超级[...]等.

我希望能够做到这样的事情,最终:

val family = new Family with SerializableFamily with TraversableFamily with FooFamily {}
Run Code Online (Sandbox Code Playgroud)

每个mixin在家庭中的一个或多个类型中添加一组协作方法.

这是我通过使用隐式包装器,基于模式匹配的访问者等解决的常见模式.但由于它只是常规mixin模式的递归应用程序,我想知道是否可能有更简单的方法来实现它.

Ale*_*nov 5

在你的情况下,错误是意料之中的,因为DogPerson中混入不覆盖 Dog,并PersonFamily,让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
  }
}
Run Code Online (Sandbox Code Playgroud)

但是你有一些令人讨厌的东西

new Family with SerializableFamily with TraversableFamily with FooFamily {
  type DogType = super[SerializableFamily].Dog with super[TraversableFamily].Dog with super[FooFamily].Dog
}
Run Code Online (Sandbox Code Playgroud)