Reputation: 1450
I'm trying to import a bunch of methods from one class to another without extending it. I've made it work but why one approach works and the other doesn't is beyond me.
Stripped down, here is what I'm trying to do
class A {def x() {println("x")}}
object A
class B {
import A._
def y() {x()}
}
And the compiler tells me "not found: value x"
But it works if I do either this
class C extends A
class B {
import C._
or if I do this
object C extends A
class B {
import C._
Can someone explain why this is the case?
Upvotes: 0
Views: 2819
Reputation: 404
There also the possibility of using implicits.
You need to have a way to get from a instance of B to the desired instance of A. In the example below I use a member value, but it should be possible to make it a function as well.
The trait exposed exposes the this in B to the implicits declared in A. The trait PathTo can be used to expose a path to the desired instance of A.
class A {
def a1(){ println("a1") };
def a2(){ println("a2") };
def a3(){ println("a3") };
}
object A{
def a1()(implicit a:A){a.a1};
def a2()(implicit a:A){a.a2};
def a3()(implicit a:A){a.a3};
//makes it possible to use a1() instead of a1()(this.a)
implicit def insertPathToA(implicit path:PathTo[A]):A=path.pathTo;
// Makes it possible to write this.a2() instead of this.a.a2();
implicit def convertPathToA(path:PathTo[A]):A=path.pathTo;
};
trait exposed[U]{
implicit def self:U=this.asInstanceOf[U];
}
trait PathTo[U]{
implicit def pathTo:U;
}
class B(val a:A) extends exposed[B] with PathTo[A] {
// imports the magic
import A._
override def pathTo:A=a;
def y() {
a1() ;
this.a2();
};
}
Upvotes: 0
Reputation: 53348
The reason why your code example class C extends A
is not working is that you import class members which can only exist in the class they are defined.
Whereas when you write object C extends A
you will create a singleton (in Scala called object like the keyword) which represents an instance and allows you to import its members.
So, to make members of other classes visible you always have to extend them, either by an object or by another class/trait. It is not enough to declare a companion object of a class because it does not hold an instance of its companion class.
Upvotes: 3