I'm in a situation where I have a need to mix in a trait defined in another package. To assist with testing, a protected method in this trait is package qualified. Here is an example:
package A {
trait X {
protected[A] def method(arg: Int)
}
}
package B {
class Y extends A.X {
protected[A] def method(arg: Int) { }
}
}
Compiling this with scalac 2.9.1 yields:
test.scala:9: error: A is not an enclosing class
protected[A] def method(arg: Int) { }
Changing the "protected[A]" in class Y to any other access modifier results in this:
test.scala:9: error: overriding method method in trait X of type (arg: Int)Unit;
method method has weaker access privileges; it should be at least protected[A]
override protected def method(arg: Int) { }
My question is this: Assuming the definition of trait X can not change, is there any change to class Y that would allow it to extend trait X? (while retaining some level of 'protected' access)
If this is not possible, are there any other recommended design strategies to work around this? (other than making 'method' public)
I ended up solving this with an adapter. While I can't change the original trait, I can add another in the same package (but for other reasons it wouldn't make sense to put the class Y in that package). The 'adapterMethod' in class Y is qualified to package B as an experiment, but most likely this is unnecessary for my use case. The following compiles in scala 2.9.1:
package A {
trait X {
protected[A] def method(arg: Int)
}
trait PackageAdapter {
protected[A] def method(arg: Int) { adapterMethod(arg) }
protected def adapterMethod(arg: Int)
}
}
package B {
class Y extends A.X with A.PackageAdapter {
protected[B] def adapterMethod(arg: Int) { }
}
}
I'm not crazy about this solution, but it isn't so bad. Class Y is a bit of an exception case as the rest of the classes that use trait X are in package A (class Y must be in package B for many other reasons). Any better ideas?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With