【问题标题】:Overriding generic function using sub-class type parameter使用子类类型参数覆盖泛型函数
【发布时间】:2020-05-15 12:19:33
【问题描述】:

我在 kotlin 中有以下接口,不可修改,因为它是在第三方库中定义的。我想使用子类的类型参数覆盖泛型方法:

interface Factory {
    fun <T> create(modelClass: Class<T>): T
}


// The naive solution doesn't compile :  "Class is not abstract and does not implement abstract member":
class ConcreteFactory1 <T> (val creator: () -> T) : Factory {
    override fun create(modelClass: Class<T>): T {
        return creator()
    }
}


// If we introduce a second type parameter, it compiles, but generates a "Unchecked Cast" warning:
class ConcreteFactory2 <T> (val creator: () -> T) : Factory {
    override fun <T2> create(modelClass: Class<T2>): T2 {
        return creator() as T2
    }
}

有没有办法在没有编译警告的情况下实现这一点?

【问题讨论】:

    标签: generics kotlin


    【解决方案1】:

    这取决于。 该接口要求您能够处理任何可能的Class&lt;T&gt; 而您的实现则不能。

    所以问题是,当create 被调用的类型不是你的ConcreteFactory2 可以创建的类型时,你想做什么?

    如果您只想看到未经检查的演员表,您可以这样做:

    class ConcreteFactory2 <T> (val creator: () -> T) : Factory {
        override fun <T2> create(modelClass: Class<T2>): T2 {
            return creator() as? T2 ?: throw IllegalArgumentException("unsupported type")
        }
    }
    

    但这是否是该接口的可接受实现实际上取决于它的使用方式。

    【讨论】:

    • 警告仍然存在这个解决方案Unchecked cast: T to T2
    • 由于类型没有被具体化,我认为安全的转换运算符不会起作用。当它返回时,您只会得到一个 ClassCastException,而不是更多信息的 IllegalArgumentException。但是,如果您在构造函数中有一个 KClass 属性,那么这种方法可能会起作用,因此可以对类型进行具体化并检查其真实性。
    • 我错了。那只会具体化 T,而不是 T2。没有办法具体化 T2,所以你不能安全地施放它。
    • 哎呀,抱歉没试过
    猜你喜欢
    • 1970-01-01
    • 2018-06-20
    • 1970-01-01
    • 2013-09-11
    • 1970-01-01
    • 2019-08-12
    • 2012-05-20
    • 2020-07-16
    • 2012-09-09
    相关资源
    最近更新 更多