4

I am learning about abstract classes,this link is very informative

scala generic method overriding

abstract class Foo[T] { self:T =>
   def bar1(f:T):Boolean
   def bar2(f:T):T
}

class FooImpl extends Foo[FooImpl]{
   override def bar1(f:FooImpl) = true
   override def bar2(f:FooImpl) = f
}

What does self:T stands for?T is class parameter as I understand.

Community
  • 1
  • 1
MotaF
  • 605
  • 2
  • 9
  • 22
  • 4
    That's a self type which enforce that any subtype of `Foo` must itself be the type parameter given to `Foo` – cchantep Jan 25 '17 at 18:21

1 Answers1

3

As @cchantep mentioned in his comment, self : T in this case is a self type annotation basically saying that an instance of Foo[T] needs also to behave as a T. You can see that is indeed the case in FooImpl, as FooImpl <: Foo.

You can find out more about self type annotation here, here or here. Notice how, most of the times, you will see it used in the context of Dependency Injection and the Cake Pattern.

Most interesting from the second link is I think the initial section:

In other words, what is the point of doing this:

trait A
trait B { this: A => }

when you could instead just do this:

trait A
trait B extends A

Why should you use [this syntax]?

[...] the answer generally comes down to "B requiring A" (annotations) vs "B being an A" (inheritance) and that the former is better for dependency management.

Finally, and just to clarify, note that the word self is not necessary at all. This could be any valid variable name, but self or this are most of the time as a convention. That is, you could be doing:

trait A 
trait B { myVar: A => }

but that would be less common.

Community
  • 1
  • 1
mdm
  • 3,928
  • 3
  • 27
  • 43