John
John

Reputation: 2707

In Scala is there a way to specify that the return type should match the type of the method caller?

For example, I have a class called Foo

abstract class Foo {
    def f(): ??? = { ... }
}
class Bar extends Foo {
    ...
}
class Baz extends Foo {
    ...
}

What I'd like is a way for f to return a Bar when it's called by Bar, and a Baz when it's called by Baz. Both Bar and Baz would have the same constructor, so the code in f would be the same both times, except for whether I have to say new Bar(...) or new Baz(...). Is there any way to say new TypeOfWhateverClassIsCallingMe(...)?

Upvotes: 2

Views: 200

Answers (2)

Alfredo Gimenez
Alfredo Gimenez

Reputation: 2224

Sounds like you want F-Bounded types. You'll still have to implement it for all subclasses however, as the parent class has no knowledge of the child constructors (A "Mammal" does not know how to make a "Cat").

abstract class Foo[T <: Foo[T]] {
    def createMe(): T
}

class Bar extends Foo[Bar] {
    override def createMe() = new Bar
}

class Baz extends Foo[Baz] {
    override def createMe() = new Baz
}

This basically gives you compile-time safety, all children of Foo need to implement a method that creates something of its own class.

In-depth discussion here.

Upvotes: 2

Thilo
Thilo

Reputation: 262534

Assuming you want the type of the concrete subclass the method is called on (I would not call this the "type of the method caller", rather the "type of the invokee"), you can do

def f(): this.type = ???

Upvotes: 1

Related Questions