我在学习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)