为什么可以在其定义范围之外看到对象的受保护内部 class?

Why protected inner class of object may be seen outside of its definition scope?

考虑以下几点:

scala> :paste
// Entering paste mode (ctrl-D to finish)

object O {
  protected case class I(x: Int)
  trait T {
    protected def m: I = I(0)
  }
}

val i = new O.T { override def m = super.m }.m

// Exiting paste mode, now interpreting.

defined object O
i: O.I = I(0)

scala> :type i
O.I

如果我在 val i 之后添加 : O.I 此代码片段无法编译,但语句 i.x 编译并且 returns 0 在运行时。

这是编译器错误还是有充分的理由出现这种行为?

派生的 classes 在任何情况下都可以 因为它们可以完全访问基础 class 受保护的成员。考虑下面的 public 方法 foo

val i = new O.T {
  override protected def m = super.m
  def foo = m
}

我们将m保持为protected,但是i.foo间接"brakes out"保护并评估为res0: O.I = I(0)。所以看起来我们通过防止覆盖覆盖没有得到太多。

同时考虑 When overriding a method, why can I increase access but not decrease it? 的相关答案:

It's a fundamental principle in OOP: the child class is a fully-fledged instance of the parent class, and must therefore present at least the same interface as the parent class.