2014-01-05 8 views
6

Ich habe eine abstrakte Klasse im Paket foo (in diesem speziellen Fall ein Merkmal), die von verschiedenen Unterklassen implementiert werden kann, und ich möchte eine orthogonale Unterklasse für die Verwendung in einem spezielleren Paket bar, die Paket-spezifische hinzufügt Info. Es scheint der beste Weg zu sein, durch Komposition (Wrapping) statt durch Vererbung, denn sonst müsste ich paketspezifische Versionen jeder einzelnen der foo -package-Unterklassen deklarieren. Aber dies führt zu einem Problem mit geschützten Elementen, die weitergeleitet werden müssen:idiomatische Möglichkeit, geschützte Methode in Scala zu deklarieren, wenn man die Zusammensetzung zulässt?

package foo { 
    trait Foo { 
    protected def bar: Int 
    } 
} 

package bar { 
    import foo.Foo 
    class Baz 
    class WrapFoo(wrapped: Foo) extends Baz with Foo { 
    protected def bar = wrapped.bar 
    } 
} 

Dies führt zu einem Fehler:

~/test/scala 14:54 152272% scalac testprotected.scala 
testprotected.scala:11: error: method bar in trait Foo cannot be accessed in foo.Foo 
Access to protected method bar not permitted because 
prefix type foo.Foo does not conform to 
class WrapFoo in package bar where the access take place 
    protected def bar = wrapped.bar 
           ^
one error found 

Obwohl WrapFoo ist eine Unterklasse von Foo, scala nicht wie die Anruf wrapped.bar. Ich vermute, das liegt daran, dass das Objekt vom Typ WrapFoo kein Unterobjekt von wrapped ist.

Die Frage ist: Was ist der idiomatische Weg, die Schutzmaßnahmen auf bar zu erklären, außer es einfach öffentlich zu machen? Die Funktion bar soll von anderen Funktionen in Foo, nicht öffentlich aufgerufen werden. Scala hat ein expressives Schutzsystem, aber ich verstehe es nicht ganz. Ist das überhaupt möglich?

Antwort

1

Wenn beide Typen in einem gemeinsamen Paket gespeichert werden, kann es sich um eine beliebige Stelle in der Pakethierarchie handeln und muss kein direktes übergeordnetes Element sein.

Dann können Sie protected[packagename] oder private[packagename] verwenden, um den Zugriff selektiv zu steuern.

+0

Ist das der einzige Weg? In meinem Fall bewirkt dies, dass der Code für das gesamte Programm zugänglich wird. Das Layout des Pakets ist schon lange etabliert, und das Umjustieren nur dafür würde viele andere Dinge durcheinander bringen. –

Verwandte Themen