Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inheriting a package-protected method by a class in a different package

Tags:

scala

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)

like image 671
nu11ptr Avatar asked Nov 05 '22 08:11

nu11ptr


1 Answers

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?

like image 70
nu11ptr Avatar answered Nov 15 '22 05:11

nu11ptr