5

我在 Scala 中有一个特征、一个伴侣对象和一个类:

trait A {
    protected var foo = "Foo"
}

object B extends A {
}

class B {
     println(B.foo)
}

为什么我无法访问 foo?我认为 foo 会成为对象“B”的一个字段。有没有办法做到这一点?

4

2 回答 2

7

该规范说您可以从以下位置访问受保护的成员:

任何这些类的伴随模块[以定义模板为基础]。

也就是说,不是来自以定义模板为基础的对象的伴随类。棘手。

由于“模块”命名法,这并不明显,其中模块仅表示对象。偶尔有人谈论改变这一点。虽然类和模块可以是伙伴关系,但关系不是对称的;考虑隐式搜索。

trait A {
  protected var foo = "Foo"
  protected def bar = "Bar"
}

object B extends A {
  //override protected var foo = super.foo // no
  override protected def bar = super.bar
}

class B {
  //println(B.foo) // no
  println(B.bar) // ok
}


class C extends A

object C {
  println(new C().foo)  // ok
}
于 2012-12-05T01:41:33.903 回答
4

Scala 默认使用公共字段。它也有私有和受保护的。私有修饰符的工作方式与 Java 相同,但受保护的工作方式截然不同。

第一个区别是 protected 可以有两种形式:protectedprotected[bar]. wherebar可以是类、包或对象。

来自Scala 语言规范

仅当满足以下条件之一时,受保护的标识符 x 才可以用作选择 r.x 中的成员名称:

– 访问在定义成员的模板内,或者,如果给定了限定 C,则在包 C、类 C、或它的伴随模块内,或

– r 是 this 和 super 的保留字之一,或者

– r 的类型符合包含访问权限的类的类型实例。

换句话说,非参数化的受保护字段仅对来自同一个包的子类不可见

于 2012-12-04T23:12:14.017 回答