Reputation: 816
class CharacterFilter extends Filter[Character] {
def _name(n: String) = { data = data.filter(c => c.name == n) }
}
class NPCFilter extends CharacterFilter {
def name(n: String) = { _name(n); this }
}
class PlayerFilter extends CharacterFilter {
def name(n: String) = { _name(n); this }
}
I'm building some classes that filter through data. NPCFilter
and PlayerFilter
should share methods from CharacterFilter
. However, I want each filter to return themselves at the end so that I can chain functions like this:
.name("John").age(18).race(WHITE)
At first I tried this, but it doesn't give the result I want, because I am left with a CharacterFilter
after calling name
instead of a NPCFilter
or PlayerFilter
as desired.
class CharacterFilter extends Filter[Character] {
def name(n: String) = { data = data.filter(c => c.name == n); this }
}
class NPCFilter extends CharacterFilter {
}
class PlayerFilter extends CharacterFilter {
}
So my first example works exactly how I want it to, but it feels repetitive (especially once I add more functions). Is there a way to make it more concise?
Upvotes: 1
Views: 212
Reputation: 29538
For this particular case where you return this
, there is a direct support :
def f(....) : this.type = ....
Writing that, this
is the only valid return value, and the compiler will type it just as it typed the target of the call to f
.
Short of that particular case, if your return type is somewhat tied to the type of the target, but not necessarily this
, you need a type member, or a generic, such as
abstract class A[T <: A[T]] {self: T =>
def f(....): T
}
class B extends A[B] { ... }
Upvotes: 4