繁体   English   中英

Kotlin:覆盖(并指定)通用接口函数

[英]Kotlin: Override (and specify) generic interface functions

我想使用将由它们的实现类指定的通用接口,并且所有这些都运行良好,例如:

interface Remove <E> { fun remove(entity: E) }

class MyHandler : Remove <MyClass> {
   override fun remove(entity: MyClass) { */do stuff/* }
}

但是,我有一个案例(到目前为止,期待更多),我希望函数本身是通用的。 写接口完全没有问题:

interface FindByID <E> { fun <K : Serializable> findByID(id: K): E }

我需要 K 是可序列化的,因为这是我需要调用的某些函数的要求。

编译器似乎不同意我的实现尝试。 当我这样做时:

override fun <String> findByID(id: String): User {
    return someFunction(User::class.java, id) as User
}

我收到两个编译器错误:

  1. 什么都不覆盖
  2. id不可序列化

但是,当我从签名中删除override<String> ,它工作正常。 这意味着String是可序列化的,我的研究也表明了这一点。

这里似乎有什么问题?

另外,是的,我知道我可以通过几种方式解决这个问题,比如

  • 使接口函数接受Serializable而不是<K : Serializable>
  • 未在覆盖时指定K ,而是在调用时指定 ( myHandler.findByID<String>("myID") )
  • “重新路由”调用,在 MyHandler 中实现(不覆盖)一个接受字符串的函数,然后在内部调用覆盖函数

尽管对建议持开放态度,但我对解决方法不太感兴趣,但更愿意了解并(如果可能)解决实际问题,或者至少知道它无法完成,因此我可以将其考虑在内进行规划

当前的问题

使用您当前的<String>声明,您并没有像您想象的那样专门化类型参数。 您实际所做的是声明一个恰好名为String的类型参数(与众所周知的String类型无关,只是一个不幸的名称冲突)。 使用语法着色,您应该看到此处的String是类型参数的颜色,而不是与 String 类型相同的颜色。 将此名称更改为其他任何名称,您就会意识到混乱。

因此,如果我们将其重命名为K ,问题就变得明显了:问题 1“什么都不覆盖”是因为您的泛型类型参数没有与接口中定义的findByID方法相同的: Serializable约束。 问题2源于它。

解决方案

另外,是的,我知道我可以通过几种方式解决这个问题,比如

  • 未在覆盖时指定 K,而是在调用时指定 (myHandler.findByID("myID"))

这一点实际上是问题的本质,而不是解决方法:在您的界面中定义一个泛型函数实际上使它成为该函数通用的契约的一部分。 实现在这里必须有一个泛型类型参数。

如何修复它取决于您期望发生的事情。

如果您同意在您的实现中使用泛型函数,那么保留您声明的接口,但接受实现必须处理K所有可能值,这很可能不是您在这里想要的。

如果你想在你的实现中定义一个特定的类型, K应该是接口定义的一部分(不是接口方法),并且该方法本身不应该有类型参数,而只是从接口中接受现有的K

interface FindByID<E, K : Serializable> {
  fun findByID(id: K): E
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM