Reputation: 381
I've got an interface IMyInterface with a method
fun myMethod(thing: T){}
I also have a class
class MyClass : IMyInterface{}
What I want is that when I implement the members of the interface it automatically sets the type T to be MyClass. Is there a way of doing that? So, instead of writing
interface IMyInterface <T>{
fun myMethod(thing: T){}
}
class MyClass: IMyInterface<MyClass>{
override fun myMethod(thing: MyClass){} // <<<-- the type is set because I explicitly set it above
}
I want to have something like this:
interface IMyInterface{
fun myMethod(thing: T){}
}
class MyClass: IMyInterface{
override fun myMethod(thing: MyClass){} // <<<-- the template type <T> of the interface is resolved by the compiler by checking what type I provided in method signature (
}
Or maybe getting a type of the class implementing an abstract class.
Upvotes: 0
Views: 64
Reputation: 170713
There is another problem which Thomas Cook's answer doesn't cover: even if this was possible, you run into major problems with subtyping in at least two ways.
Let's assume a keyword Self
which means what you want and
interface IMyInterface{
fun myMethod(thing: Self): Unit
}
Problem 1: You have a val x: IMyInterface = ...
What can you pass to x.myMethod
? Certainly not any IMyInterface
, that would defeat the purpose. But the only thing which is guaranteed to have the same concrete type as x
is... x
(assuming no Self
-returning methods).
Problem 2: Add class MySubClass : MyClass
. It must have override fun myMethod(thing: MySubClass)
, right? But it also has to inherit override fun myMethod(thing: MyClass)
from MyClass
.
Upvotes: 0
Reputation: 4853
What you are wanting to do is not possible. You want the compiler to "Magically" figure out what the template parameter is... think about it; how would it know - there is a potentially infinite subset of IMyInterface
. It is not implied in your interface that the template type <T>
is even of type IMyInterface
, so it could literally be any type...
Here is another angle on the problem that may make it clear why the compiler cannot do this:
// The same interface as your example, but with extra method
interface IMyInterface{
fun myMethod(thing: T){}
fun myOtherMethod(thing: T){}
}
// The same implementation as before, except the extra method is overridden with a different type than the first method
class MyClass: IMyInterface{
// the template type <T> of the interface is resolved by the compiler by
// checking what type I provided in method signature (this is what you want compiler to do)
override fun myMethod(thing: MyClass){}
// Uh oh! How does the copmpiler resolve this? We just figured out that <T> was my class.
// So this method won't compile... why not just tell entire class what <T> is
// rather than trying to make all method signatures match up so the compiler can "infer" the type???
override fun myOtherMethod(thing: MyOtherClass) {}
}
class MyOtherClass : IMyInterface {
override fun myMethod(thing: MyOtherClass) = this
override fun myOtherMethod(thing: MyOtherClass) = this
}
Upvotes: 1