2014-01-05 4 views
6

私はさまざまなサブクラスで実装できるfooの抽象クラスを持っています(この特定のケースでは、特性)、より具体的なパッケージbarで使用する直交サブクラスを作成したいと思います。情報それ以外の場合は、foo -packageサブクラスのすべてのパッケージ固有のバージョンを宣言しなければならないため、継承よりも合成(ラッピング)が最善の方法です。しかし、これは転送する必要が保護されたメンバーとの問題につながる:合成を許可するときにScalaで保護されたメソッドを宣言する慣用句?

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 
    } 
} 

これはエラーにつながる:

~/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 

WrapFooFooのサブクラスですが、Scalaは好きではありませんwrapped.barに電話してください。これは、タイプWrapFooのオブジェクトがwrappedのサブオブジェクトではないためです。

質問は次のとおりです。barで保護を宣言するための慣用方法は何ですか? barは、公開されていないFooの他の関数によって呼び出されることを意味します。 Scalaは表現力豊かな保護システムを持っていますが、私はそれをあまり理解していません。これはまったく可能ですか?

答えて

1

両方のタイプを共通のパッケージに入れると、パッケージ階層のどこにでも置くことができ、直接の親である必要はありません。

次に、アクセスを選択的に制御するために、protected[packagename]またはprivate[packagename]を使用できます。

+0

これが唯一の方法ですか?私の場合、これはコードをプログラム全体にアクセス可能にする効果があります。パッケージのレイアウトはすでに長い間確立されており、このためだけにrejiggeringは他の多くのものを混乱させるでしょう。 –

関連する問題