我在学习Scala时遇到了困难。我有一个继承层次结构,基本上等同于:
class A {
protected def myMethod() = println("myMethod() from A")
}
class B extends A {
def invokeMyMethod(a: A) = a.myMethod()
}
但是尝试编译这个示例,我收到错误“test.scala:7:error:方法myMethod无法在A中访问”。
来自Java,我的理解是受保护的成员应该可以在派生类的任何位置访问,而且我在任何地方都看不到任何告诉我Scala中的受保护成员受实例限制的内容。有人对此有解释吗?
答案 0 :(得分:17)
引用Scala Language Specification:
受保护的标识符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!
}