2013-11-29 3 views
0

Итак, я хочу создать абстрактную модель наследования с использованием признаков. Я думаю, что пример кода работает лучше всего, поэтому я создал эту небольшую витрину, чтобы представить свою проблему.Scala abstract inheritance

trait Animals{ 
val owned: Seq[Animal] 
type Animal <: TAnimal 
trait TAnimal { 
    def name : String 
} 
} 

Пока все хорошо. Теперь у меня есть еще одна черта «Собаки». Собаки сколы, поэтому у них есть идентификационный номер. Также я хочу реализовать последовательность, содержащую всех собак, которые у меня есть (скажем, у меня есть 5 собак со случайными именами и случайная идентификация для простоты).

trait Dogs extends Animals{ 
type Dog <: TDog 
val owned = ??? 
trait TDog extends TAnimal { 
    def identNo : Int 
} 
} 

Проблема в том, что животные или собаки являются только типами, я не могу создавать конкретные экземпляры из них. Я думаю, что могу использовать что-то вроде Seq.fill, но я не могу создать соответствующее выражение.

ответ

2

Это называется шаблон торта. И вам не нужно писать все эти вещи в собак черты, вы можете определить это следующим образом:

trait Animals{ 
type Animal <: TAnimal 
def owned: Seq[Animal] 
trait TAnimal { 
    def name : String 
} 
} 

trait Dogs extends Animals{ 
type Animal <: TDog 
trait TDog extends TAnimal { 
    def identNo : Int 
} 
} 

Затем «в конце мира» вы собираете свой торт с какой-либо конкретной реализации:

trait ReservoirDogs extends Dogs { 
    case class Animal(name: String, identNo: Int) extends TDog 
    val owned = List(Animal("Pink", 1), Animal("Blue", 2)) 
} 

Теперь вы можете смешать его в:

scala> val dogs = new Dogs with ReservoirDogs {} 
dogs: Dogs with ReservoirDogs = [email protected] 

scala> val dogs = new Animals with ReservoirDogs {} 
dogs: Animals with ReservoirDogs = [email protected] 

Это то, что торт шаблон все о

+0

Спасибо, что действительно помогло. Пока не знал о шаблоне пирога. Btw. Мне очень нравится ваш пример =) – norathem