[英]How to override inherited getter from java class in a kotlin companion object
[英]How to override method with inherited class in Kotlin?
我正在探索并积极在生产中使用 generics 和 Kotlin。
Kotlin + generics 对我来说是一个大难题,所以与 Java 相比,也许你可以在这里解释并帮助我理解它是如何工作的。
我有 class AbstracApiClient
(不是很抽象)
class AbstracApiClient {
open protected fun makeRequest(requestBuilder: AbstractRequestBuilder) {
// ...
}
}
AbstractRequestBuilder
(不是很抽象):
open class AbstractRequestBuilder {
...
}
继承AbstractApiClient
的ConcreteApiClient
应该使用从AbstractRequestBuilder
继承的ConcreteRequestBuilder
覆盖 makeRequest :
class ConcreteApiClient: AbstractApiClient() {
protected override fun makeRequest(requestBuilder: ConcreteRequestBuilder) {
// ...
}
}
class ConcreteRequestBuilder: AbstractRequestBuilder()
因为我会有更具体的 API 客户端。 我想做一个抽象,我可以传递继承的具体请求构建器并覆盖`make requests 方法。
protected open fun <R: ApiRequestBuilder> make request(request builder: R)
但它不匹配覆盖 function 我希望它是: protected override fun make request(request builder: ConcreteRequestBuilder)
我还有什么其他选择? 我在这里错过了什么吗?
注意:在这种情况下,我不能使用interface
或abstract classes
,所以理想情况下,我想找到一种使用 inheritance 和函数覆盖的方法。
您不能使用更具体的参数类型覆盖方法,因为它违反了Liskov 的替换原则:
val client: AbstractApiClient = ConcreteApiClient()
client.makeRequest(AbstractRequestBuilder())
正如您在上面看到的, ConreteApiClient
实现必须能够处理父类 class 的所有可能输入,因为它可以通过父类的 API 访问。
要做你想做的,你需要通过 generics 限制父 class 本身:
open class AbstractApiClient<R : AbstractRequestBuilder> {
open protected fun makeRequest(requestBuilder: R) {
// ...
}
}
class ConcreteApiClient: AbstractApiClient<ConcreteRequestBuilder>() {
protected override fun makeRequest(requestBuilder: ConcreteRequestBuilder) {
// ...
}
}
这样, AbstractApiClient<R>
的任何实例都必须显示它接受哪种类型的请求构建器(在 type 参数中)。 它可以防止上述问题,因为现在父类型也携带信息:
// doesn't compile
val client: AbstractApiClient<AbstractRequestBuilder> = ConcreteApiClient()
// this compiles
val client: AbstractApiClient<ConcreteRequestBuilder> = ConcreteApiClient()
我试过这个符号保护的开放乐趣 <R: ApiRequestBuilder> 发出请求(请求生成器:R)
现在关于这个尝试的实现,它不起作用,因为如果你使方法通用(不是class ),这意味着该方法的每个实现都必须处理各种R
(不是一个R
)。 将泛型放在 class 上允许为 class 的每个实例指定一次泛型参数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.