正しく理解すれば、特性はJavaインターフェイスに最も近いものであり、クラスコンストラクターは変数を自動的に設定します。
しかし、特性を拡張するクラスと、特性から変数を設定するコンストラクターがある場合、次のようになります。
trait Foo {
var foo: String
}
class Bar (foo: String) extends Foo { /* ... */ }
foo
オブジェクトを作成するときに、特性のBar
文字列を設定する場所。
コンパイラはこれについてエラーを出してくれたようです。これを達成する正しい方法は何ですか?
Bar
は抽象を定義する必要がありますvar foo
in Foo
(val
でも同じになります)。これはコンストラクタで実行できます
class Bar(var foo: String) extends Foo{...}
(もちろん、それはBar
の本体でも行うことができます)。デフォルトでは、コンストラクターのパラメーターは、必要に応じてプライベートval
になります。つまり、メソッドで初期化コードの外部で使用されます。ただし、val
またはvar
をマークすることで動作を強制でき、場合によっては可視性を制御できます
class X(protected val s: String, private var i: Int)
ここでは、var
を実装するためのパブリックFoo
が必要です。
trait Foo { var foo: String = _ }
class Bar(foo0: String) extends Foo { foo = foo0 }
特性は、初期化されていない変数を宣言します。次に、クラスはそれを入力パラメーターに等しく設定します。
あるいは、
trait Foo {
def foo: String
def foo_=(s: String): Unit
}
class Bar(var foo: String) extends Foo {}
fooに対応するゲッター/セッターのペアを宣言します。これらはクラスによって設定されます。