fun main() {
val main: MainAbstract = Main()
val stranger = main.initPerson<Stranger>()
}
abstract class MainAbstract {
abstract fun <T : Person> initPerson(): T
}
class Main : MainAbstract() {
override fun <T : Person> initPerson(): T = Student() as T
}
open class Person
class Student : Person()
class Stranger : Person()
Of course, because T is Stranger in this case. You can’t cast Student to Stanger. The value of T declared like this will be inferred from the location where you call the method, like val stranger : Stranger = initPerson(), not from the thing you actually return.
If you just want to return something that extends person, write abstract fun initPerson() : Person instead.
That works in Java completely the same as in Kotlin.
In Java you could override an abstract Person initPerson()
with an @Override Student initPerson()
and in Kotlin you can override an abstract fun initPerson() : Person
with an override fun initPerson() : Student.
In both cases, you don’t need generics.
public abstract class MainAbstract {
public abstract <T extends Person> T initPerson();
}
class Main extends MainAbstract{
@Override
public Student initPerson() {
return new Student();
}
}
class Person {}
class Student extends Person {}
That gives a warning in Java and is completely unsafe for the reasons we told you:
Unchecked overriding: return type requires unchecked conversion. Found 'Student', required 'T'
Kotlin is completely right in not allowing that.
Is there a reason why you can’t simply use Person as return value in AbstractMain instead of doing this generic stuff.
Thank you so much for you help, I think you are right, Java will got warning as well. Ok, I will remove the generic type will do the job. Thank you again