Наследование и повторное использование кода в составных чертах
В этом упрощенном эксперименте я хочу иметь возможность быстро создать класс с наращиваемыми характеристиками, который может сообщать о том, какие характеристики использовались для его построения. Это сильно напоминает мне образец декоратора, но яЯ предпочел бы реализовать это во время компиляции, а не во время выполнения.
Рабочий пример с избыточным кодом
class TraitTest {
def report(d: Int) : Unit = {
println(s"At depth $d, we've reached the end of our recursion")
}
}
trait Moo extends TraitTest {
private def sound = "Moo"
override def report(d: Int) : Unit = {
println(s"At depth $d, I make the sound '$sound'")
super.report(d+1)
}
}
trait Quack extends TraitTest {
private def sound = "Quack"
override def report(d: Int) : Unit = {
println(s"At depth $d, I make the sound '$sound'")
super.report(d+1)
}
}
проведение(new TraitTest with Moo with Quack).report(0)
затем сообщит:
> At depth 0, I make the sound 'Quack'
At depth 1, I make the sound 'Moo'
At depth 2, we've reached the end of our recursion
К сожалениюТам много избыточного кода, который заставляет мой глаз дергаться. Моя попытка убрать это приводит меня к:
Нерабочий пример без избыточного кода
class TraitTest {
def report(d: Int) : Unit = {
println(s"At depth $d, we've reached the end of our recursion")
}
}
abstract trait Reporter extends TraitTest {
def sound : String
override def report(d: Int) : Unit = {
println(s"At depth $d, I make the sound '${sound}'")
super.report(d+1)
}
}
trait Moo extends Reporter {
override def sound = "Moo"
}
trait Quack extends Reporter{
override def sound = "Quack"
}
Когда мы снова выполняем(new TraitTest with Moo with Quack).report(0)
Теперь мы видим:
> At depth 0, I make the sound 'Quack'
At depth 1, we've reached the end of our recursion
Вопрос 1: Где линия дляMoo» идти? Я
Я предполагаю, что Скала видит толькоoverride def report(d: Int)
один раз, и, следовательно, только помещает его в цепочку наследования один раз. Я'Я хватаюсь за соломинку, но если этоВ таком случае, как я могу обойти это?
Вопрос 2: Как каждая конкретная черта может обеспечить уникальность?sound
Решив первый вопрос, я бы предположил результаты выполнения(new TraitTest with Moo with Quack).report(0)
будет выглядеть примерно так, в связи с тем, как наследованиеsound
должно сработать.
> At depth 0, I make the sound 'Quack'
At depth 1, I make the sound 'Quack'
At depth 2, we've reached the end of our recursion
Как мы можем сделать так, чтобы каждая черта использовалаsound
указано в немс реализацией?