【问题标题】:How to create a class with a method that returns a subtype with a type parameter in Kotlin?如何使用在 Kotlin 中返回带有类型参数的子类型的方法创建一个类?
【发布时间】:2021-04-21 14:22:24
【问题描述】:

我很难理解泛型/类型参数在 Kotlin 中的工作原理。我正在开发一个(相当复杂的)应用程序,该应用程序在编译期间会抛出一些非常令人困惑的错误消息。我已将以下内容简化为能够重现错误的最少代码量。

我有一个接口和两个抽象类:

interface Player {
    fun play()
}

abstract class Device <T : Player> {
    abstract fun getPlayer(): T
}

abstract class DeviceFactory {
    abstract fun <T : Player> create(): Device<T>
}

当我尝试创建一个实现DeviceFactory的类时出现问题:

class MyDeviceFactory : DeviceFactory() {
    
    class MyPlayer : Player {
        override fun play() {
            println("[sound plays here]")
        }
    }
    
    class MyDevice : Device<MyPlayer>() {
        override fun getPlayer() = MyPlayer()
    }
    
    override fun create() = MyDevice()
}

最后一行代码是问题出现的地方,产生以下错误消息:

冲突重载:public open fun create(): MyDeviceFactory.MyDevice 定义在 MyDeviceFactory,
public abstract fun create(): DeviceFactory中定义的设备

认为问题可能是缺少类型参数,我尝试了这个:

override fun <T : Player> create() = MyDevice()

现在我收到一条不同的错误消息:

“create”的返回类型不是被覆盖成员的返回类型的子类型 'public abstract fun create(): DeviceFactory 中定义的设备'

这没有意义——MyDeviceDevice&lt;T&gt; 的子类型,对吧?可以肯定的是,我尝试明确返回类型:

override fun <T : Player> create(): Device<T> = MyDevice()

没有骰子:

类型不匹配:推断的类型是 MyDeviceFactory.MyDevice 但需要设备

如何创建一个派生自DeviceFactory 并返回MyDevice 实例的类?

【问题讨论】:

    标签: kotlin generics type-parameter


    【解决方案1】:

    您需要在其类上声明DeviceFactory 的类型:

    abstract class DeviceFactory<T : Player> {
        abstract fun create(): Device<T>
    }
    

    然后你可以定义一个返回具体 Player 的工厂:

    class MyDeviceFactory : DeviceFactory<MyPlayer>() {
        override fun create(): Device<MyPlayer> = MyDevice()
    }
    

    【讨论】:

    • out 是多余的,会导致编译错误
    • @IR42 你是对的,out 是多余的。我更新了我的答案。谢谢。虽然它不会导致我的代码出现编译错误。
    猜你喜欢
    • 1970-01-01
    • 2012-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-27
    • 2015-01-08
    • 2015-07-12
    • 1970-01-01
    相关资源
    最近更新 更多