I'd like to have a trait that can a) be mixed into any class with a particular method, and b) can call super. Something like this:
// A and B are from a library that I don't control. No changes allowed here.
class A {
def stuff = "a stuff"
}
class B {
def stuff = "b stuff"
}
// My code starts here
type HasStuffMethod = {
def stuff: String
}
// Note that this doesn't compile - gets:
// class type required but AnyRef{def stuff: String} found
trait ImplementsStuff extends HasStuffMethod {
override def stuff = "trait + " + super.stuff
}
val a = new A with ImplementsStuff
assert(a.stuff == "trait + a stuff")
val b = new B with ImplementsStuff
assert(b.stuff == "trait + b stuff")
Is there any way to do this?
Note that I don't control A and B; they're coming from another library that I can't modify.
[Edit - added after seeing answers]
Is there a way to call the original method in something like this?
trait ImplementsStuff {
this: HasStuffMethod =>
abstract override def stuff = "foo" + "how do I call the original method here?"
}
This isn't useful, since when you mix it into something it gives:
error: overriding method stuff in class A of type => java.lang.String; method stuff in trait ImplementsStuff of type => java.lang.String cannot override a concrete member without a third member that's overridden by both (this rule is designed to prevent ``accidental overrides'')
But it's no accident; yes, I really do want you to step all over that existing method. And then let me call it, too.