scala中private和private[Class]声明的区别是什么?

scala中private和private[Class]声明的区别是什么?,scala,Scala,下面的类编译。如果存在任何差异,我如何看到这两个范围之间的差异 class C1 { private val p = 0 private[C1] val pClass = 1 def m1(other: C1) { println(other.p) println(other.pClass) } } 它们几乎是等价的,并且在所有常见用例中肯定是等价的 但是,两者之间实际上有一个非常微小的语义差异: private限制对封闭类C1及其伴生对象的访问,但子类不继

下面的类编译。如果存在任何差异,我如何看到这两个范围之间的差异

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

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

它们几乎是等价的,并且在所有常见用例中肯定是等价的

但是,两者之间实际上有一个非常微小的语义差异:

  • 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
private
(无需覆盖),并且如果
override
被删除,则
display
将返回
1
而不是
2
,则不会编译此代码

因此,基本上,除非有内部类扩展类本身,
private[C1]
的行为与
private
完全相同


注意此外,由于上述原因,它们在字节码级别的实现方式不同:

  • private val p
    创建:
    • 私有字段
      p
    • 和私有访问器方法
      p()
  • 但是
    private[C1]val类创建:
    
    • 私有字段
      C1$$pClass
    • 和一个公共访问器方法
      C1$$pClass()

它们几乎是等价的,并且在所有常见用例中都是等价的

但是,两者之间实际上有一个非常微小的语义差异:

  • 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
private
(无需覆盖),并且如果
override
被删除,则
display
将返回
1
而不是
2
,则不会编译此代码

因此,基本上,除非有内部类扩展类本身,
private[C1]
的行为与
private
完全相同


注意此外,由于上述原因,它们在字节码级别的实现方式不同:

  • private val p
    创建:
    • 私有字段
      p
    • 和私有访问器方法
      p()
  • 但是
    private[C1]val类创建:
    
    • 私有字段
      C1$$pClass
    • 和一个公共访问器方法
      C1$$pClass()