Kotlin - 具有泛型返回类型的抽象函数

时间:2023-01-02 21:17:48

I am new to Kotlin and really worried whether I am writing proper syntax or not. I have a super class and I want to write a generic abstract function as below.

我是Kotlin的新手并且非常担心我是否正在编写正确的语法。我有一个超类,我想写一个通用的抽象函数,如下所示。

abstract class A {
    abstract fun <T> getText() : Test<T>
}

class B : A() {
    override fun <T> getText(): Test<T> {
        return Test1() // Error - Required Test<T>, found Test1
    }
}

class C : A() {
    override fun <T> getText(): Test<T> {
        return Test2() // Error - Required Test<T>, found Test2
    }
}

class Test1 : Test<String>() {

}

class Test2 : Test<Int>() {

}

Can I solve this kind of problem with some sort of proper syntax. I guess I am doing some mistake? Can anybody please help?

我可以用某种正确的语法解决这类问题吗?我猜我做错了吗?有人可以帮忙吗?

3 个解决方案

#1


3  

This is the answer you're looking for:

这是您正在寻找的答案:

abstract class A<T> {
    abstract fun getText() : Test<T>
}

class B : A<String>() {
    override fun getText(): Test<String> = Test1()
}

class C : A<Int>() {
    override fun getText(): Test<Int> = Test2()
}

class Test1 : Test<String>()
class Test2 : Test<Int>()
open class Test<T>

You just need to move parameter T from the method signature to the class.

您只需将参数T从方法签名移动到类。

Bonus: I updated the above snippet to more idiomatic Kotlin

额外奖励:我将上述片段更新为更加惯用的Kotlin

#2


3  

What you're doing cannot be correct, because it would allow the following code:

你正在做的事情是不正确的,因为它将允许以下代码:

val test: Test<Int> = B().getText()

B().getText() tries to return Test1(), which is Test<String>. But because the return type can be anything, its valid. This breaks the type system.

B()。getText()尝试返回Test1(),即Test 。但因为返回类型可以是任何东西,它的有效性。这打破了类型系统。

#3


2  

You likely want to enforce the type from the class rather than the method, due to Kiskae's example.

由于Kiskae的例子,您可能希望从类而不是方法强制执行类型。

For example:

例如:

abstract class A<T> {
    abstract fun getText() : Test<T>
}

can be extended using

可以使用扩展

class B : A<String>() ...

which will match the type for Test1

这将匹配Test1的类型

#1


3  

This is the answer you're looking for:

这是您正在寻找的答案:

abstract class A<T> {
    abstract fun getText() : Test<T>
}

class B : A<String>() {
    override fun getText(): Test<String> = Test1()
}

class C : A<Int>() {
    override fun getText(): Test<Int> = Test2()
}

class Test1 : Test<String>()
class Test2 : Test<Int>()
open class Test<T>

You just need to move parameter T from the method signature to the class.

您只需将参数T从方法签名移动到类。

Bonus: I updated the above snippet to more idiomatic Kotlin

额外奖励:我将上述片段更新为更加惯用的Kotlin

#2


3  

What you're doing cannot be correct, because it would allow the following code:

你正在做的事情是不正确的,因为它将允许以下代码:

val test: Test<Int> = B().getText()

B().getText() tries to return Test1(), which is Test<String>. But because the return type can be anything, its valid. This breaks the type system.

B()。getText()尝试返回Test1(),即Test 。但因为返回类型可以是任何东西,它的有效性。这打破了类型系统。

#3


2  

You likely want to enforce the type from the class rather than the method, due to Kiskae's example.

由于Kiskae的例子,您可能希望从类而不是方法强制执行类型。

For example:

例如:

abstract class A<T> {
    abstract fun getText() : Test<T>
}

can be extended using

可以使用扩展

class B : A<String>() ...

which will match the type for Test1

这将匹配Test1的类型