Dziedziczenie i ponowne wykorzystanie kodu w cechach możliwych do układania w stosy
W tym uproszczonym eksperymencie chcę być w stanie szybko zbudować klasę z cechami stosu, które mogą raportować, jakie cechy zostały użyte do jej zbudowania. Przypomina mi to mocno wzór dekoratora, ale wolę mieć to zaimplementowane w czasie kompilacji niż w czasie wykonywania.
Przykład pracy z kodem nadmiarowym
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)
}
}
Wykonywanie(new TraitTest with Moo with Quack).report(0)
zgłosiłbym wtedy:
> 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
Niestety, jest tam dużo zbędnego kodu, który sprawia, że moje oko drży. Moja próba oczyszczenia prowadzi mnie do:
Nie działający przykład bez kodu nadmiarowego
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"
}
Kiedy znów wykonamy(new TraitTest with Moo with Quack).report(0)
, teraz widzimy:
> At depth 0, I make the sound 'Quack'
At depth 1, we've reached the end of our recursion
Pytanie 1: Gdzie poszła linia do „Moo”?
Zgaduję, że Scala tylko widzioverride def report(d: Int)
raz, a zatem raz umieszcza go w łańcuchu dziedziczenia. Chwytam się słomy, ale jeśli tak jest, jak mogę to obejść?
Pytanie 2: W jaki sposób każda konkretna cecha może zapewnić wyjątkowysound
?
Po rozwiązaniu pierwszego pytania zakładałbym wyniki wykonywania(new TraitTest with Moo with Quack).report(0)
wyglądałby jak poniżej, ze względu na sposób dziedziczeniasound
pracowałbym.
> 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
Jak możemy to zrobić, aby każda cecha używałasound
określony w jego implementacji?