Kotlin 接口方法默认值和传递依赖项

问题描述 投票:0回答:1

我有一个系统,其类/接口层次结构分布在 3 个库中。它的玩具版本看起来像这样:

A图书馆:

interface BaseInterface {
  fun foo(): String
}

B图书馆:

class Impl : BaseInterface {
  override fun foo(): String {
    return "foo!"
  }
}

在C库中:

class SomethingUnrelated {
  fun doAThing() {
     val i: BaseInterface = Impl()
     println(i.foo())
  }
}

到目前为止,一切都很好。库 C 依赖于库 B 和库 A。一切正常。

现在假设我发布了库 A 的新版本,并且添加了一个具有默认实现的新方法:

interface BaseInterface {
  fun foo(): String
  fun newMethod(): Int = 0
}

我想将它带入库C并更改

doAThing
以使用它,如下所示:

class SomethingUnrelated {
  fun doAThing() {
     val i: BaseInterface = Impl()
     println(i.foo() + " and also " + i.newMethod())
  }
}

如果我更新库 C 以引入库 A 的新版本(不触及对库 B 的依赖关系),我会得到一个

java.lang.AbstractMethodError
(这是可以理解的)。我可以重新编译库 B 并同时更新 A 和 B,但我还有一些其他限制,这让这变得很困难。

所以我的问题是:除了重新编译库 B 并将两个库同时引入 C 之外,我还有其他选择吗?我可以使用一些 kotlin 魔法来帮助解决我的问题吗?

感谢您的帮助!

kotlin inheritance jvm
1个回答
0
投票

Kotlin 的默认接口方法实际上默认情况下不会编译为 Java 默认接口方法。如果他们这样做了,你就不会得到

AbstractMethodError

要使 Kotlin 默认方法编译为 Java 默认方法,请添加

-Xjvm-default=all
编译器选项。然后清理并重新编译库 A 和 C。

当你需要重新编译库B时,你也应该使用此选项编译它,或者用

BaseInterface
标记
@JvmDefaultWithCompatibility
,否则可能是二进制不兼容。

另请参阅:https://kotlinlang.org/docs/java-to-kotlin-interop.html#default-methods-in-interfaces

© www.soinside.com 2019 - 2024. All rights reserved.