[英]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.