63

クイック ノート: チュートリアルScala for Java Refugees Part 5: Traits and Typesの例。

私が学生、労働者、低賃金、および若いという特性を持っているとします。

これらすべての特性を持つクラス ( instance ではない) CollegeStudentを宣言するにはどうすればよいでしょうか?

注:私は、1 つまたは 2 つの Traits を持つ CollegeStudent など、最も単純なケースを認識しています。

class CollegeStudent extends Student with Worker
4

2 に答える 2

118

クラスを宣言するときは、「with」キーワードを好きなだけ使用するだけです。

class CollegeStudent extends Student with Worker with Underpaid with Young

トレイトがクラスの動作を変更する場合、トレイトの順序が重要になる可能性があります。それはすべて、使用しているトレイトに依存します。

また、常に同じ特性を使用するクラスを持ちたくない場合は、後でそれらを使用できます。

class CollegeStudent extends Student
new CollegeStudent with Worker with Underpaid with NotSoYoungAnymore
于 2009-07-05T19:58:08.697 に答える
18

構文だけでなく、トレイトの順序付けがどのような役割を果たしているのかを説明することは非常に重要だと思います。Jason Swartz のLearning Scala (page 177) の説明は非常に啓発的でした。

  • Scala クラスは一度に複数のトレイトを拡張できますが、JVM クラスは 1 つの親クラスしか拡張できません。Scala コンパイラーは、「各特性のコピーを作成して、クラスと特性の背の高い単一列の階層を形成する」ことでこれを解決します。これは線形化と呼ばれるプロセスです。

  • このコンテキストでは、同一のフィールド名を持つ複数のトレイトを拡張するとコンパイルに失敗し、「クラスを拡張して独自のバージョンのメソッドを提供するがオーバーライド キーワードの追加に失敗した場合とまったく同じ」です。

また、継承ツリーの形状が決定されるため、線形化の順序は非常に重要な問題の 1 つです。例として、class D extends A with B with C(A はクラス、B と C はトレイト) は になりclass D extends C extends B extends Aます。同じく本からの次の数行は、それを完全に示しています。

trait Base { override def toString = "Base" }
class A extends Base { override def toString = "A->" + super.toString }
trait B extends Base { override def toString = "B->" + super.toString }
trait C extends Base { override def toString = "C->" + super.toString }
class D extends A with B with C { override def toString = "D->" + super.toString }

を呼び出すとnew D()、REPL は次のように出力します。

 D->C->B->A->Base

これは、線形化された継承グラフの構造を完全に反映しています。

于 2016-10-10T13:00:38.287 に答える