1

以下のクラスがコンパイルされます。これら 2 つのスコープの違いがある場合、どうすればその違いを確認できますか?

class C1 {
  private val p = 0
  private[C1] val pClass = 1

  def m1(other: C1) {
    println(other.p)
    println(other.pClass)
  }
}
4

1 に答える 1

10

それらはほぼ同等であり、すべての一般的なユースケースで同等であることは間違いありません。

しかし、実際には、この 2 つの間には非常に小さな意味上の違いがあります。

  • privateC1外側のクラスとそのコンパニオン オブジェクトへのアクセスを制限しますが、定義はサブクラスに継承されず、親クラスの定義をオーバーライドできません。
  • private[C1]C1とそのコンパニオン オブジェクトへのアクセスも制限されますが、そのメンバーは継承され、そのクラスがアクセスできる限り、子クラスによってオーバーライドできます ( で囲まれている場合C1)。

次に例を示します。

class A {
  private[A] val i = 1

  def display() { println(i) }

  class B extends A {
    override private[A] val i = 2
  }
}

val a = new A
a.display // 1
val b = new a.B
b.display // 2 !!

Biはアクセスできるためオーバーライドでき、 の内部クラスであるためアクセスできますA。これは(オーバーライドするものiが何もない) 場合はコンパイルされず、削除された場合はand notが返されます。privateoverridedisplay12

したがって、基本的に、クラス自体を拡張する内部クラスがない限り、private[C1]まったく同じように動作しますprivate


上記のため、バイトコードレベルでは同じように実装されていないことにも注意してください:

  • private val p作成します:
    • プライベートフィールドp
    • およびプライベート アクセサー メソッドp()
  • しかし、private[C1] val pClass作成します:
    • プライベートフィールドC1$$pClass
    • およびパブリックアクセサ メソッドC1$$pClass()
于 2013-08-31T16:49:47.690 に答える