この単純化された実験では、ビルドに使用されたトレイトを報告できるスタック可能なトレイトを持つクラスをすばやくビルドできるようにしたいと考えています。これはデコレータ パターンを強く思い出させますが、これは実行時ではなくコンパイル時に実装することを好みます。
冗長コードを使用した作業例
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」のセリフはどこに行ったのですか?
Scala は1 回しか認識override def report(d: Int)
しないため、継承チェーンに 1 回だけ配置すると思います。私はストローをつかんでいますが、そうであれば、どうすればそれを回避できますか?
質問 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
各特性がその実装で指定されたものを使用するようにするにはどうすればよいでしょうか?