用可见性修饰符覆盖接口成员函数的正确语法是什么?

这两个页面, Interfaces上的 ,也不是Visibility Modifiers上的,都提供了我之后的语法的一个例子,所以我问。

我有一个像这样的界面:

package bookyard.contracts; public interface IAuthenticationManager<T> { fun authenticateUser(userName: String, password : String, appId: String, appSecret : String) : OperationResult<T>; } 

我正在为它编写一个实现,但下面列出的三个语法都不起作用。 每次编译器都会报告以下错误:

  1. “authenticateUser”不会覆盖任何内容

  2. 类'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<User> { /* override public fun authenticateUser(userName : String?, password : String?, appId : String?, appSecret : String?) : OperationResult<User> { } public override fun authenticateUser(userName : String?, password : String?, appId : String?, appSecret : String?) : OperationResult<User> { } public fun authenticateUser(userName : String?, password : String?, appId : String?, appSecret : String?) : OperationResult<User> { } */ } 

问题…

你的问题是当你尝试实现这个接口的时候,你正在使用空字符串。

从Kotlin关于无效安全的文档

在Kotlin中,类型系统区分可以容纳null(可空引用)的引用和不能引用(非空引用)的引用。

String? (可空字符串)和String被认为是Kotlin的不同类型 。 所以编译器认为你没有实现这个方法。

你的选择…

你有2个选项:

  1. 更新你的接口来使用可空的参数(在每个类型的末尾添加? )。

  2. 更新你的实现来使用不可为空的参数( String )。

我认为选项2稍微清洁,因为它不会打破任何其他现有的接口实现。

示例(对于选项2):

界面保持不变。

这是新的实施…

 package bookyard.server.util import bookyard.contracts.IAuthenticationManager class DatabaseAuthenticationManager : IAuthenticationManager<User> { override fun authenticateUser(userName : String, password : String, appId : String, appSecret : String) : OperationResult<User> { // Your implementation... } } 

你可以看到,我所做的是从String?更改每个参数String? String

笔记:

  • 类/字段/接口默认公共的public关键字是不必要的。

  • Kotlin有分号推理,所以你不需要自己添加分号。 在极少数情况下,您实际需要 ,但编译器会提前警告您。

每个重写的方法都需要符合接口声明的参数为空。 换句话说,实现接口的正确方法是:

 class DatabaseAuthenticationManager : IAuthenticationManager<User> { override fun authenticateUser(userName: String, password: String, appId: String, appSecret: String): OperationResult<User> { ... } }