用可见性修饰符覆盖接口成员函数的正确语法是什么?
这两个页面, 接口上的一个,以及Visibility Modifiers上的一个都没有提供我之后的语法的一个例子,所以我问。
我有一个像这样的界面:
package bookyard.contracts; public interface IAuthenticationManager { fun authenticateUser(userName: String, password : String, appId: String, appSecret : String) : OperationResult; }
我正在为它编写一个实现,但下面列出的三个语法都不起作用。 编译器每次都会报告以下错误:
“authenticateUser”不会覆盖任何内容
类’DatabaseAuthenticationManager’必须声明为abstract或abstract abstract成员public abstract fun authenticateUser(userName:String,password:String,appId:String,appSecret:String):在bookyard.contracts.IAuthenticationManager中定义的OperationResult
package bookyard.server.util import bookyard.contracts.IAuthenticationManager; public class DatabaseAuthenticationManager : IAuthenticationManager { /* override public fun authenticateUser(userName : String?, password : String?, appId : String?, appSecret : String?) : OperationResult { } public override fun authenticateUser(userName : String?, password : String?, appId : String?, appSecret : String?) : OperationResult { } public fun authenticateUser(userName : String?, password : String?, appId : String?, appSecret : String?) : OperationResult { } */ }
问题…
你的问题是当你尝试实现这个接口的时候,你正在使用空字符串。
从Kotlin关于无效安全的文档
在Kotlin中,types系统区分可以容纳null(可空引用)的引用和不能引用(非空引用)的引用。
String?
(可空字符串)和String
被认为是Kotlin的不同types 。 所以编译器认为你没有实现这个方法。
你的选择…
你有2个选项:
-
更新你的接口来使用可空的参数(在每个types的末尾添加
?
)。 -
更新你的实现来使用不可为空的参数(
String
)。
我认为选项2稍微清洁,因为它不会打破任何其他现有的接口实现。
示例(对于选项2):
界面保持不变。
这是新的实施…
package bookyard.server.util import bookyard.contracts.IAuthenticationManager class DatabaseAuthenticationManager : IAuthenticationManager { override fun authenticateUser(userName : String, password : String, appId : String, appSecret : String) : OperationResult { // Your implementation... } }
你可以看到,我所做的是从String?
更改每个参数String?
String
。
笔记:
-
类/字段/接口默认是公共的 ,
public
关键字是不必要的。 -
Kotlin有分号推理,所以你不需要自己添加分号。 在极少数情况下,您实际需要 ,但编译器会提前警告您。
每个重写的方法都需要符合接口声明的参数为空。 换句话说,实现接口的正确方法是:
class DatabaseAuthenticationManager : IAuthenticationManager { override fun authenticateUser(userName: String, password: String, appId: String, appSecret: String): OperationResult { ... } }