以下のクラスがコンパイルされます。これら 2 つのスコープの違いがある場合、どうすればその違いを確認できますか?
class C1 {
private val p = 0
private[C1] val pClass = 1
def m1(other: C1) {
println(other.p)
println(other.pClass)
}
}
以下のクラスがコンパイルされます。これら 2 つのスコープの違いがある場合、どうすればその違いを確認できますか?
class C1 {
private val p = 0
private[C1] val pClass = 1
def m1(other: C1) {
println(other.p)
println(other.pClass)
}
}
それらはほぼ同等であり、すべての一般的なユースケースで同等であることは間違いありません。
しかし、実際には、この 2 つの間には非常に小さな意味上の違いがあります。
private
C1
外側のクラスとそのコンパニオン オブジェクトへのアクセスを制限しますが、定義はサブクラスに継承されず、親クラスの定義をオーバーライドできません。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 !!
B
i
はアクセスできるためオーバーライドでき、 の内部クラスであるためアクセスできますA
。これは(オーバーライドするものi
が何もない) 場合はコンパイルされず、削除された場合はand notが返されます。private
override
display
1
2
したがって、基本的に、クラス自体を拡張する内部クラスがない限り、private[C1]
まったく同じように動作しますprivate
。
上記のため、バイトコードレベルでは同じように実装されていないことにも注意してください:
private val p
作成します:
p
p()
private[C1] val pClass
作成します:
C1$$pClass
C1$$pClass()