内部类的隐私和外部类型的子类型的可访问性

时间:2011-11-28 05:26:22

标签: scala private-members

我对内部类方法和构造函数的私有注释有困难。虽然这可以按预期工作:

trait A {
  protected def lala = ()
}

trait B extends A {
  lala
}

以下内容不是:

trait A {
  class Lala protected()
}

trait B extends A {
   new Lala
}

这两个都没有:

trait A {
  class Lala private[A]()
}

trait B extends A {
  new Lala
}

唯一的方法就是这样:

object Screwed {
  trait A {
    class Lala private[Screwed]()
  }

  trait B extends A {
    new Lala
  }
}

Scala真的在这里没有提供明确的机制,或者我错过了什么?我的猜测应该是private[this.type]但是scalac根本不想吞下它......

3 个答案:

答案 0 :(得分:6)

那么,

trait A {
  class Lala protected()
  new Lala
}

也不编译。错误消息似乎很合理:

 error: constructor Lala in class Lala cannot be accessed in trait A
 Access to protected constructor Lala not permitted because
 enclosing class trait A in object $iw is not a subclass of
 class Lala in trait A where target is defined

受保护的访问意味着您只能从该类或子类访问该构造函数。你试图从封闭的特征中调用它。你可以做的一件事是:

trait B extends A {
  class Gaga extends Lala
  new Gaga
}

出于类似的原因,我不希望你的第三个例子被编译。

还要注意受保护的构造函数和protected class之间的区别。例如:

trait A {
  protected class P
  class U  // unprotected
}

class B extends A {
  new P  // OK
  new U  // OK
}

val b = new B
new b.P  // error
new b.U  // OK

答案 1 :(得分:1)

这也适用于所需的可见性(Lala只能从AA的子类型实例化。

trait A {
   class Lala private[A]()
   protected def newLala = new Lala
}

trait B extends A {
   newLala
}

我想知道protected[A]之类的目的是什么,如果它在这种情况下不起作用。

答案 2 :(得分:0)

受保护的人应该可以肯定,你会得到什么错误?对于私有的,你定义的范围控制它们的可见性(因此在特征A中,如果你给出A的可见性,它在B中显然是不可见的)。在最后一个示例中,您已将范围指定为Screwed,因此Screwed中的任何内容都可以看到私有类。顺便说一句,我更喜欢将访问修饰符编写为代码行中的第一件事以便于阅读

您使用的是什么版本的scala,“你的工作”是什么意思?

HTH!