Scala中其他实例的受保护成员

Mas*_*psi 9 scala protected

我在学习Scala时遇到了困难.我有一个继承层次结构,基本上等同于:

class A {
    protected def myMethod() = println("myMethod() from A")
}

class B extends A {
    def invokeMyMethod(a: A) = a.myMethod()
}
Run Code Online (Sandbox Code Playgroud)

但是尝试编译这个示例,我得到错误"test.scala:7:error:方法myMethod无法在A中访问".

来自Java,我的理解是受保护的成员应该可以在派生类的任何位置访问,而且我在任何地方都看不到任何告诉我Scala中的受保护成员受实例限制的内容.有没有人对此有解释?

Tom*_*ett 17

引用Scala语言规范:

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

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

- r是这个和超级的保留字之一,或者

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

这三个规则定义了何时允许实例访问另一个实例的受保护成员.需要注意的一件事是,根据最后一条规则,当B扩展时A,一个实例A可以访问不同实例的受保护成员B......但是一个实例B可能无法访问另一个实例的受保护成员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!
}
Run Code Online (Sandbox Code Playgroud)

  • `B`派生自`A`,但它试图不访问自己的受保护成员`myMethod`,而是访问另一个实例的参数`a:A`.受保护的成员仅对包含it_的_instance可见(默认情况下,尽管可以使用我提到的作用域注释修改它). (2认同)