igr
igr

Reputation: 10614

Kotlin, immutable interface with 2 implementations and generics

I have the following interface:

interface Point {
    val name: String
    val position: Position
    fun move(newPosition: Position): Point
}

and have two implementations of the Point (Foo and Bar). Function move never changes the Point implementation. In other words, the implementation of the point stays the same, once created.

However, the signature of move does not say so. Is there a way to specify the return type in a such way so the return type is the same as the implementation type?

E.g.:

class A : Point {
  override fun move(newPosition: Position): Point {
     return A(name, newPosition);
  }
  ...
}
class B : Point {
  override fun move(newPosition: Position): Point {
     return B(name, newPosition);
  }
}

and then:

var a: Point = A()
...
a = a.move(newPos)

(this code requires casting and I want to avoid it).

Upvotes: 0

Views: 58

Answers (1)

Michiel
Michiel

Reputation: 768

What you should do, is use a type parameter:

interface Point<T> {
    val name: String
    val position: Position
    fun move(newPosition: Position): T
}

class A(
    override val name: String,
    override val position: Position
) : Point<A> {
    override fun move(newPosition: Position): A {
        return A(name, newPosition);
    }
}
class B(
    override val name: String,
    override val position: Position
) : Point<B> {

    override fun move(newPosition: Position): B {
        return B(name, newPosition);
    }
}

var a: A = A("", Position(2,3))
a = a.move(Position(2,3)

Upvotes: 2

Related Questions