2011-01-07 14 views
9

私はScalaを学んでいるうちに苦労しました。私はこれと本質的に同等である継承階層を持っている: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の保護されたメンバーはインスタンスによって制限されているとは言いませんでした。誰にもこれについての説明がありますか?

答えて

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.

これらの3つのルールは、インスタンスが別のインスタンスのprotectedメンバにアクセスすることを許可されたときに正確に定義します。面白いことに、BAに拡張された場合、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' _は、' A'の派生型です。 –

+2

'B'は' A'から派生していますが、それ自身の保護されたメンバ 'myMethod'ではなく、別のインスタンスのパラメータである' a:A'にアクセスしようとしています。プロテクトされたメンバはit_を含む_instanceにのみ可視です(既定では、これは私が述べたスコープの注釈で変更できます)。 –

+1

これはあなたが引用した通りに「これと同じ型の他のインスタンスと派生型を含む」というやり方とむしろ矛盾しています。 – Submonoid

関連する問題