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 中其他实例的受保护成员的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Derived 内部调用 Base 实例中的受保护成员函数?

C++ 派生模板类:访问实例的受保护成员

Python - 访问类的受保护成员_

Java中的间接子类无法访问的超类中的受保护成员

静态成员函数无法访问类的受保护成员

访问基类的受保护成员