Let's assume I have a generic type like this one:
class GenericEchoer[T <: Any] {
var content: T = _
def echo: String = "Echo: " + content.toString
}
Then it is possible to create a mixin that would allow to extend functionality of GenericEchoer[T] like this:
trait Substitution[T <: AnyRef] extends GenericEchoer[T] {
def substitute(newValue: T) = { content = newValue }
}
Having those defined, I can instantiate type in this way:
val echoer = new GenericEchoer[Int] with Substitution[Int]
My question is: how to implement similar functionality so that I can omit type parameters in the mixin? In other words, I'd like to be able to instantiate the same type with the following line:
val echoer = new GenericEchoer[Int] with Substitution
This, however, does not work, as Substitution "doesn't know" the underlying type parameter.
You code is wrong, it won't even compile.
Your GenericEchoer
cannot be a class
, cause your content
member is abstract, or you should init this with a default value:
class GenericEchoer[T <: AnyRef] {
var content: T = _
def echo: String = "Echo: " + T.toString
}
You can't write T.toString
, i guess you wanted content.toString
. You can't pass Int
to it, cause Int
has AnyVal
as its supertype, and your upper bound of T
is AnyRef
.
self.content
in Substitution
is also illegal, you should:
1) make self
as a selftype:
trait Substitution[T <: AnyRef] extends GenericEchoer[T] { self =>
def substitute(newValue: T) = { self.content = newValue }
}
2) Replace it with this
3) Just leave { content = newValue }
As for your problem. No it's not possible. I can suggest you replace class
with a trait
and type constructor with an abstract type member:
trait GenericEchoer {
type T <: AnyRef
var content: T = _
def echo: String = "Echo: " + content.toString
}
trait Substitution extends GenericEchoer {
def substitute(newValue: T) { content = newValue }
}
val enchoer = new GenericEchoer with Substitution { type T = String }
or better
val enchoer = new GenericEchoer with Substitution {
type T = String
var content = "Hello" // either case it will be null
}