Kotlin:泛型接口中泛型函数的重写问题咨询
咱们先直接戳中问题的核心——你写的<String>根本不是把接口里的泛型K指定为java.lang.String,而是在重新声明一个名为String的泛型类型参数,这直接导致了两个编译错误。
为什么会出现这两个错误?
"overrides nothing" 错误:
接口里的函数签名是fun <K : Serializable> findByID(id: K): E,而你写的fun <String> findByID(id: String): User中,<String>是在当前函数上声明了一个新的泛型参数(名字叫String,和系统的String完全无关)。这个新的泛型参数没有继承Serializable约束,而且函数签名和接口的泛型函数签名不匹配,编译器自然认为你没有重写任何接口方法。"id is not Serializable" 错误:
因为你声明的这个<String>泛型参数没有Serializable约束,所以编译器把id: String里的String当成了这个自定义的泛型类型,而不是系统自带的java.lang.String(它确实实现了Serializable)。所以编译器判定这个id的类型不满足接口要求的Serializable约束。
正确的实现方式
根据你的需求,分两种场景给出解决方案:
场景1:你的Handler只需要处理String类型的ID
如果你的UserHandler只针对String类型的ID做处理,应该把泛型K从函数层面提升到接口层面,这样实现类可以明确指定K的类型:
// 修改接口,把K作为接口的泛型参数 interface FindByID<E, K : Serializable> { fun findByID(id: K): E } // 实现类指定E为User,K为String class UserHandler : FindByID<User, String> { override fun findByID(id: String): User { return someFunction(User::class.java, id) as User } }
这样写法完全符合编译器要求,也清晰表达了你的业务意图。
场景2:你的Handler需要支持所有Serializable类型的ID
如果你的UserHandler需要处理任意实现了Serializable的ID类型,那实现时要保留函数的泛型约束,不要硬指定类型:
interface FindByID<E> { fun <K : Serializable> findByID(id: K): E } class UserHandler : FindByID<User> { // 保留泛型约束,不指定具体类型 override fun <K : Serializable> findByID(id: K): User { return someFunction(User::class.java, id) as User } }
此时调用者可以传入任何Serializable类型的ID,你的实现也能正常处理。
额外说明
你去掉override和<String>后代码能运行,是因为此时你写的是一个全新的函数(不是重写接口方法),id: String里的String是系统自带的java.lang.String,它确实实现了Serializable,所以编译器不会报错,但这并没有实现你想要的“重写接口方法”的目的。
内容的提问来源于stack exchange,提问作者Batt84

