5

Scala に Trait、Companion Object、および Class があります。

trait A {
    protected var foo = "Foo"
}

object B extends A {
}

class B {
     println(B.foo)
}

foo にアクセスできないのはなぜですか? fooはオブジェクト「B」のフィールドになると思っていました。これを行う方法はありますか?

4

2 に答える 2

7

仕様によると、保護されたメンバーにアクセスできるのは次のとおりです。

これらのクラスのいずれかのコンパニオン モジュール [ベースとして定義テンプレートを持つ]。

つまり、定義テンプレートをベースとして持つオブジェクトのコンパニオン クラスからではありません。トリッキー。

モジュールが単にオブジェクトを意味する「モジュール」命名法のため、これは明らかではありません。それを変えようという話が時々あります。クラスとモジュールはコンパニオンになることができますが、関係は対称的ではありません。暗黙の検索を検討してください。

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
}
于 2012-12-05T01:41:33.903 に答える
4

Scala はデフォルトで public フィールドを使用します。また、プライベートで保護されています。プライベート修飾子は Java と同じように機能しますが、保護されていると劇的に異なります。

最初の違いは、 protected が と の 2 つの形式を持つことができることprotectedですprotected[bar]barクラス、パッケージ、またはオブジェクトの場所。

Scala 言語仕様から:

保護された識別子 x は、次のいずれかに該当する場合にのみ、選択 r .x のメンバー名として使用できます。

– アクセスは、メンバーを定義するテンプレート内で行われるか、修飾 C が指定されている場合は、パッケージ C、クラス C、またはそのコンパニオン モジュール内で行われます。

– r は予約語 this および super のいずれか、または

– r の型は、アクセスを含むクラスの型インスタンスに準拠します。

つまり、パラメーター化されていない保護フィールドは、同じパッケージ以外のサブクラスからのみ表示されます

于 2012-12-04T23:12:14.017 に答える