Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

idiomatic way to declare protected method in Scala when allowing for composition?

I have an abstract class in package foo (in this particular case, a trait) that can be implemented by various subclasses, and I'd like to create an orthogonal subclass for use in a more specific package bar that adds package-specific info. It seems the best way is by composition (wrapping) rather than inheritance because otherwise I'd have to declare package-specific versions of every single one of the foo-package subclasses. But this leads to a problem with protected members which need to be forwarded:

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

This leads to an error:

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

Even though WrapFoo is a subclass of Foo, scala doesn't like the call wrapped.bar. I'm guessing this is because the object of type WrapFoo isn't a sub-object of wrapped.

The question is: What's the idiomatic way to declare the protections on bar other than simply making it public? The function bar is meant to be called by other functions in Foo, not publicly. Scala has an expressive protection system but I don't quite understand it. Is this possible at all?

like image 745
Urban Vagabond Avatar asked Jan 05 '14 21:01

Urban Vagabond


1 Answers

Put both types in a common package, it can be anywhere in the package hierarchy and doesn't have to be an immediate parent.

Then you can use protected[packagename] or private[packagename] to selectively control access.

like image 144
Kevin Wright Avatar answered Nov 08 '22 18:11

Kevin Wright