当前位置: 首页 > 知识库问答 >
问题:

带有默认函数参数值的Kotlin接口

楚嘉纳
2023-03-14

我想为实现接口的类中的函数参数使用默认值,如下所示:

interface FileStoreService {
    fun storeFile(path: String, payload: InputStream, type: MediaType, replace: Boolean = true)
}
kotlin prettyprint-override">class LocalFileStoreService : FileStoreService {

    override fun storeFile(path: String, payload: InputStream, type: MediaType, replace: Boolean /* ?? */) {
        // ....
    }
}

现在这里是编译的,这里是不编译的:

KO:不允许重写函数为其参数指定默认值

class LocalFileStoreService : FileStoreService {

    override fun storeFile(path: String, payload: InputStream, type: MediaType, replace: Boolean = true) {
        // ....
    }
}

KO:类“LocalFileStoreService”不是抽象的,并且没有实现抽象成员公共抽象存储文件(路径:String,负载:InputStream,类型:MediaType):fqn中定义的单元。。。文件存储服务

class LocalFileStoreService : FileStoreService {

    override fun storeFile(path: String, payload: InputStream, type: MediaType, replace: Boolean) {
        // ....
    }
}

好 啊:

class LocalFileStoreService : FileStoreService {

    override fun storeFile(path: String, payload: InputStream, type: MediaType) {
        storeFile(path, payload, type, true)
    }

    override fun storeFile(path: String, payload: InputStream, type: MediaType, replace: Boolean) {
        // ....
    }
}

这是预期的行为吗?有没有更好的方法来管理接口中的默认参数值?

共有1个答案

佴阳辉
2023-03-14

你所描述的很奇怪,因为通过尝试用静态编程语言1.4.20重现它,我看不到相同的行为。

下面的代码工作正常:

interface Test {
    fun test(p1: String, p2: Boolean = true)
}

class TestImpl : Test {
    // below commented function breaks compilation
    //override fun test(p1: String) = println("That's odd... received: $p1")

    // You cannot overwrite default value, that would break interface contract
    override fun test(p1: String, p2: Boolean) = println("It works ! Received: $p1 and $p2")
}

fun main() {
    // Default value for second parameter is deduced from interface signature 
    TestImpl().test("Hello")
}

如果我取消对没有布尔参数的函数的注释,编译就会崩溃,因为该方法不会从接口继承。

一般来说,如果在接口级别定义默认值,那么更改特定实现的默认值是个坏主意,因为这会破坏API契约。

编辑

请注意,从注释函数中删除overries关键字将产生有效的代码,因为它成为特定于实现的函数。不过,我发现这种行为很危险,因为以下程序:

interface Test {
    fun test(p1: String, p2: Boolean = true)
}

class TestImpl : Test {
    fun test(p1: String) = println("That's odd... received: $p1")
    override fun test(p1: String, p2: Boolean) = println("It works ! Received: $p1 and $p2")
}

fun main() {
    val t : Test = TestImpl()
    t.test("Hello")
    (t as TestImpl).test("Hello")
}

然后将产生以下输出:

It works ! Received: Hello and true
That's odd... received: Hello
 类似资料:
  • 对于一些函数,你可能希望它的一些参数是 可选 的,如果用户不想要为这些参数提供值的话,这些参数就使用默认值。这个功能借助于默认参数值完成。你可以在函数定义的形参名后加上赋值运算符(=)和默认值,从而给形参指定默认参数值。 注意,默认参数值应该是一个参数。更加准确的说,默认参数值应该是不可变的——这会在后面的章节中做详细解释。从现在开始,请记住这一点。 使用默认参数值 例7.5 使用默认参数值 #!

  • Scala 函数 Scala 可以为函数参数指定默认参数值,使用了默认参数,你在调用函数的过程中可以不需要传递参数,这时函数就会调用它的默认参数值,如果传递了参数,则传递值会取代默认值。实例如下: object Test { def main(args: Array[String]) { println( "返回值 : " + addInt() ); } def

  • 本文向大家介绍Kotlin函数默认值的完全讲解,包括了Kotlin函数默认值的完全讲解的使用技巧和注意事项,需要的朋友参考一下 函数默认值 周所周知,Java语言并不支持参数使用默认值。有人说这是因为“默认参数”和“方法重载”同时支持的话有二义性的问题,具体真正的原因我不得而知。但是对我个人来说,Java不支持这个特性的确挺让我蛋疼的,虽然说使用方法重载也可以间接实现与默认参数这个特性相同的功能,

  • 问题内容: 我希望JavaScript函数具有我设置了默认值的可选参数,如果未定义值,则使用该参数(如果传递值,则将其忽略)。在Ruby中,您可以这样操作: 这在JavaScript中有效吗? 问题答案: 从ES6 / ES2015开始,默认参数在语言规范中。 正常工作。 如果 未 传递 任何值 或 未定义, 则默认函数参数允许使用默认值初始化形式参数。 您还可以通过解构来模拟默认的命名参数: 预

  • 在 C++中,定义函数时可以给形参指定一个默认的值,这样调用函数时如果没有给这个形参赋值(没有对应的实参),那么就使用这个默认的值。也就是说,调用函数时可以省略有默认值的参数。如果用户指定了参数的值,那么就使用用户指定的值,否则使用参数的默认值。 所谓默认参数,指的是当函数调用中省略了实参时自动使用的一个值,这个值就是给形参指定的默认值。下面是一个简单的示例: 运行结果: 10, 3.5, # 2

  • 问题 你想定义一个函数或者方法,它的一个或多个参数是可选的并且有一个默认值。 解决方案 定义一个有可选参数的函数是非常简单的,直接在函数定义中给参数指定一个默认值,并放到参数列表最后就行了。例如: def spam(a, b=42): print(a, b) spam(1) # Ok. a=1, b=42 spam(1, 2) # Ok. a=1, b=2 如果默认参数是一个可修改的容器