2011-01-07 6 views
9

Ich hatte gerade Schwierigkeiten, Scala zu lernen. Ich habe eine Vererbungshierarchie, die im Wesentlichen äquivalent dazu ist:Geschützte Mitglieder anderer Instanzen in Scala

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

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

aber versuchen, diese Probe zu kompilieren, erhalte ich die Fehlermeldung „test.scala: 7: Fehler: Methode myMethod kann nicht in A zugegriffen werden“.

Aus Java kommend, ist mein Verständnis, dass geschützte Mitglieder zu jedem Zeitpunkt von einer abgeleiteten Klasse zugänglich sein sollten, und nirgends habe ich etwas gesehen, das mir sagt, dass geschützte Mitglieder in Scala durch Instanzen begrenzt sind. Hat jemand eine Erklärung dafür?

Antwort

17

unter Angabe der 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.

Diese drei Regeln definieren, wann genau eine Instanz erlaubt ist, eine andere Instanz geschützte Member zugreifen. Interessant ist, dass nach der letzten Regel, wenn BA erweitert, eine Instanz von A auf geschützte Mitglieder einer anderen Instanz von B zugreifen kann ... aber eine Instanz von B darf nicht auf geschützte Mitglieder einer anderen A zugreifen! Mit anderen Worten:

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

Diese Erklärung sagt eigentlich nicht, warum der OP-Code nicht funktioniert. 'B' ist eine abgeleitete Art von' A', genau wie es sein soll. –

+2

'B' ist abgeleitet von' A', aber es versucht nicht auf seinen eigenen geschützten Member 'myMethod' zuzugreifen, sondern auf den einer anderen Instanz, den Parameter' a: A'. Ein geschütztes Member ist nur für die _instance sichtbar, die es enthält (standardmäßig kann dies jedoch mit der von mir erwähnten Scoping-Anmerkung geändert werden). –

+1

Das widerspricht eher der von Ihnen zitierten Passage: "einschließlich anderer Instanzen des gleichen Typs und aller abgeleiteten Typen." – Submonoid

Verwandte Themen