Scala:访问伴随对象特征的受保护字段

时间:2012-12-04 23:03:41

标签: scala

我有一个Trait,一个Companion对象和一个Scala中的类:

trait A {
    protected var foo = "Foo"
}

object B extends A {
}

class B {
     println(B.foo)
}

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

2 个答案:

答案 0 :(得分: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
}

答案 1 :(得分:4)

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

第一个区别是受保护可以有两种形式:protectedprotected[bar]。其中bar可以是类,包或对象。

来自Scala language spec

  

受保护的标识符x可以用作选择r中的成员名称   .x仅在下列情况之一适用时:

     

- 访问权限在定义成员的模板中,或者,如果是   在包C内或C类或其中给出了定性C.   配套模块,或

     

- r是保留字和超级或

之一      

- r的类型符合包含的类的类型实例   访问。

换句话说,非参数化受保护字段只能从不是来自同一个包的子类中看到。