web-dev-qa-db-ja.com

scalaコンストラクターを使用してtraitで定義された変数を設定する

正しく理解すれば、特性はJavaインターフェイスに最も近いものであり、クラスコンストラクターは変数を自動的に設定します。

しかし、特性を拡張するクラスと、特性から変数を設定するコンストラクターがある場合、次のようになります。

trait Foo {
    var foo: String
}

class Bar (foo: String) extends Foo { /* ... */ }

fooオブジェクトを作成するときに、特性のBar文字列を設定する場所。

コンパイラはこれについてエラーを出してくれたようです。これを達成する正しい方法は何ですか?

44
Seba Kerckhof

Barは抽象を定義する必要がありますvar foo in Foovalでも同じになります)。これはコンストラクタで実行できます

class Bar(var foo: String) extends Foo{...}

(もちろん、それはBarの本体でも行うことができます)。デフォルトでは、コンストラクターのパラメーターは、必要に応じてプライベートvalになります。つまり、メソッドで初期化コードの外部で使用されます。ただし、valまたはvarをマークすることで動作を強制でき、場合によっては可視性を制御できます

class X(protected val s: String, private var i: Int)

ここでは、varを実装するためのパブリックFooが必要です。

28
Didier Dupont
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に対応するゲッター/セッターのペアを宣言します。これらはクラスによって設定されます。

33
Rex Kerr