I've always called this recursive type parameterization. It's useful
when the base class needs to know the type that it's eventually
instantiated as, usually so that it can provide implementations of
methods where dispatch is based upon the instantiated type. I've found
myself using the pattern mostly in cases where I wanted to have
parallel class hierarchies, say of model objects and rendering
strategies for those models. In this case, the model base class would
have a recursive type parameter, and the rendering strategy would be
parameterized with respect to the model type.

ex:

class Model[T <: Model[T]] {
   self: T =>
   def render(r: Renderer[T]) {
      r.render(this)
   }
}

class ConcreteModel extends Model[ConcreteModel]

class Renderer[T <: Model[T]] {
   abstract def render(model: T)
}

class ConcreteModelRenderer extends Renderer[ConcreteModel] {
   def render(model: ConcreteModel) { ... }
}

In Java, you have a little more boilerplate because you don't have an
explicit self-type, so you have to define an abstract method self: T
which you implement trivially in each subclass.

Recursive self-types can be really useful but they're definitely a
double-edged sword because they're sort of viral; you have to add a
bunch of boilerplate type information everywhere that you refer to the
base type, and if you ever discard the more specific type information
(in the example above, say by putting a bunch of different subclasses
of Model into a List[Model[_]]) then you can never get it back without
reflection, and any use of the members of that list in a contravariant
position (say as an argument to another method call) becomes
impossible.

Kris

On Fri, Jun 19, 2009 at 12:18 AM, Eric Bowman<[email protected]> wrote:
>
> The basic trick where a superclass has its subclass as a type parameter,
> e.g.
>
> class User extends MegaProtoUser[User]
>
> I've run into this before, I remember struggling to "get it", then
> getting it, but I can't recall the epiphany.  But obviously this is a
> relatively common technique, so something to google is much appreciated.
>
> Thanks,
> Eric
>
> --
> Eric Bowman
> Boboco Ltd
> [email protected]
> http://www.boboco.ie/ebowman/pubkey.pgp
> +35318394189/+353872801532
>
>
> >
>

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Lift" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to