我有一个Trait,一个Companion对象和一个Scala中的类:
trait A {
protected var foo = "Foo"
}
object B extends A {
}
class B {
println(B.foo)
}
为什么我不能访问foo?我以为foo会成为对象“B”的一个字段。有没有办法做到这一点?
答案 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一样工作,但受保护,工作方式截然不同。
第一个区别是受保护可以有两种形式:protected
和protected[bar]
。其中bar
可以是类,包或对象。
受保护的标识符x可以用作选择r中的成员名称 .x仅在下列情况之一适用时:
- 访问权限在定义成员的模板中,或者,如果是 在包C内或C类或其中给出了定性C. 配套模块,或
- r是保留字和超级或
之一- r的类型符合包含的类的类型实例 访问。
换句话说,非参数化受保护字段只能从不是来自同一个包的子类中看到。