Michael Lorton
Michael Lorton

Reputation: 44436

How does a trait refer to the implementing class?

For example, I want to declare a trait to say in effect, "If class C implements this trait, it has a method m that returns an instance of class C".

All the ways I can think of just say that m returns an instance having that trait, which is not what I want at all.

Upvotes: 1

Views: 198

Answers (2)

AmigoNico
AmigoNico

Reputation: 6862

You constrain the "self type" like so:

scala> trait Foo[Self] { self:Self => def m:Self }
defined trait Foo

scala> class A extends Foo[A] { def m = new A }
defined class A

scala> class B extends Foo[A] { def m = new B }
<console>:27: error: illegal inheritance;
 self-type B does not conform to Foo[A]'s selftype Foo[A] with A
       class B extends Foo[A] { def m = new B }
                       ^
<console>:27: error: type mismatch;
 found   : B
 required: A
       class B extends Foo[A] { def m = new B }
                                        ^

scala> class B extends Foo[B] { def m = new A }
<console>:27: error: type mismatch;
 found   : A
 required: B
       class B extends Foo[B] { def m = new A }

Upvotes: 4

serejja
serejja

Reputation: 23881

If I understood your question correctly, you must be looking for something like this:

trait Foo[T] {
  def m: T
}

class A extends Foo[A] {
  def m = {
    getInstanceOfAFromSomewhere()
  }
}

class B extends Foo[B] {
  def m = {
    getInstanceOfBFromSomewhere()
  }
}

Testing:

object Test extends App {
  val a: Foo[_] = new A
  println(a.m)

  val b: Foo[_] = new B
  println(b.m)
}

Output:

A@3d246f44
B@14a1373f

Hope this is what you are looking for

Upvotes: 1

Related Questions