2011-01-07 172 views
9

其他情况下的保护成员我只是遇到了一个困难,而学习Scala。我有一个继承层次是基本相同的:在斯卡拉

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

class B extends A { 
    def invokeMyMethod(a: A) = a.myMethod() 
} 

但是,试图编译这个示例中,我得到的错误“test.scala:7:错误:方法myMethod的不能在访问”。我的理解是受保护的成员应该可以从派生类的任何位置访问,并且我没有看到任何可以告诉我Scala中的受保护成员受实例限制的任何东西。有没有人对此有过解释?

回答

17

引述Scala Language Specification

A protected identifier x may be used as a member name in a selection r .x only if one of the following applies:

– The access is within the template defining the member, or, if a qualification C is given, inside the package C, or the class C, or its companion module, or

– r is one of the reserved words this and super, or

– r ’s type conforms to a type-instance of the class which contains the access.

这三条规则确定什么时候一个实例被允许访问另一个实例的保护成员。有一点需要注意的是,根据最后一条规则,当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! 
} 
+1

这个解释实际上并没有说明为什么OP的代码不起作用。 `B` _is_是派生类型`A`,就像它应该是的一样。 – 2011-01-07 10:00:47