Scala 中其他实例的受保护成员
Posted
技术标签:
【中文标题】Scala 中其他实例的受保护成员【英文标题】:Protected Members of Other Instances in Scala 【发布时间】:2011-06-05 01:04:18 【问题描述】:我在学习 Scala 时遇到了困难。我有一个基本上等同于这个的继承层次结构:
class A
protected def myMethod() = println("myMethod() from A")
class B extends A
def invokeMyMethod(a: A) = a.myMethod()
但尝试编译此示例时,我收到错误“test.scala:7: error: method myMethod cannot be access in A”。
来自 Java,我的理解是受保护的成员应该可以在任何时候从派生类访问,而且我在任何地方都没有看到任何东西告诉我 Scala 中的受保护成员受实例限制。有人对此有解释吗?
【问题讨论】:
【参考方案1】:引用Scala Language Specification:
受保护的标识符 x 可以用作选择 r .x 中的成员名称 仅当满足以下条件之一时:
– 访问在定义成员的模板内,或者,如果给定了限定条件 C,则在包 C、类 C 或其伴随模块内,或者
--r是this和super的保留字之一,或者
– r 的类型符合包含访问权限的类的类型实例。
这三个规则定义了一个实例何时可以访问另一个实例的受保护成员。值得注意的一点是,根据最后一条规则,当B
扩展A
时,A
的实例可以访问B
的不同实例的受保护成员...但@987654326 的实例@ 不能访问另一个 A
的受保护成员!换句话说:
class A
protected val aMember = "a"
def accessBMember(b: B) = b.bMember // legal!
class B extends A
protected val bMember = "b"
def accessAMember(a: A) = a.aMember // illegal!
【讨论】:
这个解释实际上并没有说明为什么 OP 的代码不起作用。B
是 A
的派生类型,就像它应该的那样。
B
派生自A
,但它试图访问的不是它自己的受保护成员myMethod
,而是另一个实例的参数a: A
。受保护的成员仅对包含它的实例可见(默认情况下,尽管可以使用我提到的范围注释进行修改)。
这与您引用的段落相矛盾:“包括相同类型的其他实例和任何派生类型。”
@Submonoid - 你是完全正确的,报价并不真正适用。请查看我对回复的修改。
-1 这个答案应该是 3-5 句长。编辑之前的一切都是浪费时间。以上是关于Scala 中其他实例的受保护成员的主要内容,如果未能解决你的问题,请参考以下文章