2011-01-07 173 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