Scala に Trait、Companion Object、および Class があります。
trait A {
protected var foo = "Foo"
}
object B extends A {
}
class B {
println(B.foo)
}
foo にアクセスできないのはなぜですか? fooはオブジェクト「B」のフィールドになると思っていました。これを行う方法はありますか?
Scala に Trait、Companion Object、および Class があります。
trait A {
protected var foo = "Foo"
}
object B extends A {
}
class B {
println(B.foo)
}
foo にアクセスできないのはなぜですか? fooはオブジェクト「B」のフィールドになると思っていました。これを行う方法はありますか?
仕様によると、保護されたメンバーにアクセスできるのは次のとおりです。
これらのクラスのいずれかのコンパニオン モジュール [ベースとして定義テンプレートを持つ]。
つまり、定義テンプレートをベースとして持つオブジェクトのコンパニオン クラスからではありません。トリッキー。
モジュールが単にオブジェクトを意味する「モジュール」命名法のため、これは明らかではありません。それを変えようという話が時々あります。クラスとモジュールはコンパニオンになることができますが、関係は対称的ではありません。暗黙の検索を検討してください。
trait A {
protected var foo = "Foo"
protected def bar = "Bar"
}
object B extends A {
//override protected var foo = super.foo // no
override protected def bar = super.bar
}
class B {
//println(B.foo) // no
println(B.bar) // ok
}
class C extends A
object C {
println(new C().foo) // ok
}
Scala はデフォルトで public フィールドを使用します。また、プライベートで保護されています。プライベート修飾子は Java と同じように機能しますが、保護されていると劇的に異なります。
最初の違いは、 protected が と の 2 つの形式を持つことができることprotected
ですprotected[bar]
。bar
クラス、パッケージ、またはオブジェクトの場所。
Scala 言語仕様から:
保護された識別子 x は、次のいずれかに該当する場合にのみ、選択 r .x のメンバー名として使用できます。
– アクセスは、メンバーを定義するテンプレート内で行われるか、修飾 C が指定されている場合は、パッケージ C、クラス C、またはそのコンパニオン モジュール内で行われます。
– r は予約語 this および super のいずれか、または
– r の型は、アクセスを含むクラスの型インスタンスに準拠します。
つまり、パラメーター化されていない保護フィールドは、同じパッケージ以外のサブクラスからのみ表示されます。