Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/amazon-web-services/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Function Kotlin:重写(并指定)通用接口函数_Function_Kotlin_Generics_Interface_Overriding - Fatal编程技术网

Function Kotlin:重写(并指定)通用接口函数

Function Kotlin:重写(并指定)通用接口函数,function,kotlin,generics,interface,overriding,Function,Kotlin,Generics,Interface,Overriding,我希望使用通用接口,这些接口将由它们的实现类指定,而且所有这些都工作得很好,比如: interface Remove <E> { fun remove(entity: E) } class MyHandler : Remove <MyClass> { override fun remove(entity: MyClass) { */do stuff/* } } interface Remove{fun Remove(实体:E)} 类MyHandler:删除{ 覆

我希望使用通用接口,这些接口将由它们的实现类指定,而且所有这些都工作得很好,比如:

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

class MyHandler : Remove <MyClass> {
   override fun remove(entity: MyClass) { */do stuff/* }
}
interface Remove{fun Remove(实体:E)}
类MyHandler:删除{
覆盖乐趣删除(实体:MyClass){*/do stuff/*}
}
但是,我有一个例子(到目前为止,还期待更多的例子),我希望函数本身是泛型的。编写接口完全没有问题:

interface FindByID <E> { fun <K : Serializable> findByID(id: K): E }
接口FindByID{fun FindByID(id:K):E}
我需要K是可序列化的,因为这是我需要调用的某个函数的要求

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

override fun <String> findByID(id: String): User {
    return someFunction(User::class.java, id) as User
}
覆盖findByID(id:String):用户{
以用户身份返回someFunction(User::class.java,id)
}
我发现两个编译器错误:

  • 凌驾于任何事物之上
  • id
    不可序列化
  • 但是,当我从签名中删除
    覆盖
    时,它可以正常工作。这意味着
    String
    是可序列化的,我的研究也表明了这一点

    这里有什么问题吗

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

    • 使接口函数接受可序列化的
      而不是
    • 在重写时不指定
      K
      ,而是在调用时指定(
      myHandler.findByID(“myID”)
    • “重新路由”调用,在MyHandler中实现(而不是重写)一个接受字符串的函数,然后在内部调用重写的函数
    尽管我愿意接受建议,但我对变通办法不太感兴趣,但我更愿意理解并(如果可能)解决实际问题,或者至少知道这是不可能的,这样我就可以在规划当前问题时考虑到这一点 使用当前的
    声明,您并没有像您所想的那样专门化类型参数。实际上,您正在声明一个名为
    String
    的类型参数(与众所周知的
    String
    类型无关,只是一个不幸的名称冲突)。使用语法着色,您应该看到
    String
    这里是类型参数的颜色,而不是字符串类型的颜色。把这个名字改成别的名字,你就会意识到混淆

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

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

    • 未在重写时指定K,但在调用时指定K(myHandler.findByID(“myID”))
    这一点实际上是问题的本质,而不是解决方法:在接口中定义泛型函数实际上使其成为通用函数契约的一部分。 这里的实现必须具有泛型类型参数

    如何修复它取决于您预期会发生什么

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

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

    接口FindByID{
    FunFindByid(id:K):E
    }
    
    如果我遵循,接口承诺您可以使用任何类型调用该方法
    K
    ——但您的实现试图将其限制为特定类型,这就是为什么不允许这样做的原因。 您是否尝试将类型参数
    K
    向上移动到界面? 然后您可以在实现类中修复它。谢谢!我曾考虑过你最后的建议(K是接口定义的一部分),但将其作为另一个“解决方案”放弃了,因为我基本上是脑力劳动者,不知何故认为我可以稍后将重写和重载结合起来,即使用相同的函数(
    findByID(id)
    )通过为K提供不同的类型来重载。考虑到每个实现都是模糊的(
    findbyID(Serializable)
    ),我意识到这是愚蠢的