Kotlin 接口(interface)类型参数

标签 kotlin generics

我有一个场景,需要将对象编码为 XML。该对象可以是多个类型,因此我创建了一个接口(interface),将该对象类型设置为通用 T。

interface FileMarshaller<T> {
    fun marshal(object: T): File
}

我将有这个接口(interface)的几种实现,每种类型的对象都有一个实现。这是一个:

internal class DocumentFileMarshaller : FileMarshaller<Document> {

    override fun marshal(document: Document): File {
        //some kotlin code
    }
}

这很好,满足我的需要。问题出在工厂。该工厂接收一个参数并根据该参数决定应检索哪个编码器。

class FileMarshallerFactory {

    internal fun createMarshaller(fileType: FileTypes): FileMarshaller<What should I put here?> {
        when (fileType) {
            FileTypes.DOCUMENT -> {
                return DocumentFileMarshaller()
            }
            else -> throw MarshallerNotFound(MARSHALLER_NOT_FOUND)
        }
    }
}

问题出在工厂的返回类型上。我不能将其留空,我不能将 Document 作为它的类型,因为我将有更多的实现。我该如何处理这个类型参数?也许除了我创建的这个工厂之外还有另一种方法?

最佳答案

在您的情况下,FileTypes 确定结果类型是什么,并且它始终与特定类型相关,因此对其进行参数化也是有意义的。然后将其用作T的“源”:

class FileMarshallerFactory {

    @Suppress("UNCHECKED_CAST")
    internal fun <T> createMarshaller(fileType: FileTypes<T>): FileMarshaller<T> {
        when (fileType) {
            FileTypes.DOCUMENT -> {
                return DocumentFileMarshaller() as FileMarshaller<T>
            }
            else -> throw MarshallerNotFound(MARSHALLER_NOT_FOUND)
        }
    }
}

sealed interface FileTypes<T> {
    object DOCUMENT : FileTypes<Document>
}

请注意,这种方法不能使用枚举。您需要一个密封的接口(interface)/类。

而且,说实话,这个代码设计让我感觉有点奇怪。如果编码器的数量有限,并且调用者需要知道它到底获取了哪个编码器,则它必须知道 DocumentFileTypes.DOCUMENT,然后就不会'为每个编码器建立单独的工厂不是更容易吗?要么通过多个函数,要么通过完全独立的类。也许这是因为我们看到的不是完整的图片,而是一个简化的示例。

关于Kotlin 接口(interface)类型参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75620439/

相关文章:

使用泛型的 Java 工厂,.class 与 .getClass()

android - 如何准备要发布的 Jetpack compose 应用程序,@Preview 可组合项呢?

android - 为全屏 Activity 摆脱不必要的根布局

java - Kotlin Random和Java Random之间的分布差异

xcode - 具有特定颜色的特定字母?

c# - 通用 OrderedDictionary : How to get an index of a key?

java - 使用通用通配符代替接口(interface)

android - 如何实现 LiveData 单例

android - 为什么我在 Kotlin 中键入 View 名称/ID 时会出现 "unresolved reference"错误?

c# - 是否可以在引入其他泛型类型的泛型类上使用构造函数?