這是我的代碼:
interface ClaseA<I: ClaseB, V: ClaseC> /span>{
fun otherMethod( item: I, holder: V)
}
interface ClaseB{
fun getViewType(): String
}
抽象 class ClaseC {
抽象 fun someMethod()
}
class HijoB: ClaseB {.
override fun getViewType() = "Prueba"
}
class HijoC: ClaseC() {
override fun someMethod() {
print("一些方法,hijoC")
}
}
class HijoA: ClaseA<HijoB, HijoC> {
override fun otherMethod( item: HijoB, holder: HijoC) {
println(item.getViewType())
println(holder.someMethod())
}
}
fun main() {
val list。MutableList<ClaseA<out ClaseB, out ClaseC> > = mutableListOf()
val hijoA: ClaseA<HijoB, HijoC> = HijoA()
val hijoB: HijoB = HijoB()
val hijoC: HijoC = HijoC()
list.add(hijoA)
list.forEach { item -> item.otherMethod(hijoB, hijoC) }
println("Hello, world!!")
}
我在Kotlin Playground中放了一段示例代碼:
我不希望鑄造串列中的專案。
當我按下播放鍵時,我遇到的錯誤是:
型別不匹配:推斷出的型別是HijoB,但沒有預期的東西。 型別不匹配:推斷的型別是HijoC,但沒有預期的東西
。uj5u.com熱心網友回復:
你的通用變數在這里有一個問題。
你的代碼的開頭可能看起來沒問題:
HijoA是--ClaseA<HijoB, HijoC>根據HijoA的定義。
ClaseA<HijoB, HijoC>是ClaseA<out ClaseB, out ClaseC>的一個子型別,根據out的定義差異然而,問題是,就ClaseA<out ClaseB, out ClaseC>方法而言,你對otherMethod沒有任何辦法。
讓我澄清一下:
out ClaseB意味著"ClaseB的某個子型別" 。
out ClaseC意味著"ClaseC的一些子型別" 。
- 方法
otherMethod以I和V為引數,所以在ClaseA<out ClaseB, out ClaseC>,它接受"ClaseB的某個子型別"和"ClaseC的某個子型別"作為引數,但我們不知道是哪一個(當看到這個型別時,你不知道實際的實體到底接受什么) - 任何方法都可以接受其引數的子型別(這是繼承的一般規則) 。
鑒于上述情況,ClaseA<out ClaseB, out ClaseC>給我們的資訊太少,以至于唯一能保證方法otherMethod接受的引數是:
- 第一個引數:
ClaseB的每個可能的子型別 。
- 第二個引數:
ClaseC的每個可能的子型別的子型別 。
結論:對于兩個引數來說,唯一可以普遍接受的型別是層次結構底部的型別,它是每個型別的子型別。Nothing。這實質上意味著你不能以任何有意義的方式呼叫方法otherMethod。
解決方案
你必須對該串列的元素型別進行更具體的說明,以使這些元素變得有用:你必須對該串列的元素型別進行更具體的說明。
val list。MutableList<ClaseA<HijoB, HijoC>> = mutableListOf()
或者
val list: MutableList<HijoA> = mutableListOf()
注意,你最終出現了這個問題,因為你試圖宣告一個與ClaseA的方差實際應該是相反的方差。它只接受I和V作為inputs(方法引數),所以你可以這樣宣告你的介面:
interface ClaseA< in I: ClaseB, in V: ClaseC> {
fun otherMethod( item: I, holder: V)
這將在早期突出顯示list的宣告存在問題。
然而,如果你在ClaseA中還有其他方法回傳型別為I或V的值,那么你將不能使用這個宣告位的差異。那么你可以堅持使用你現有的ClaseA的宣告。但是你仍然要修復list的宣告。
uj5u.com熱心網友回復:
你的串列輸入不正確。
你的串列應該是:
val list: MutableList<HijoA> = mutableListOf()
OR
val list: MutableList<ClaseA<HijoB, HijoC>> = mutableListOf()
否則,你就不符合你所定義的介面。通過將MutableList定義為:
val list: MutableList<ClaseA<out ClaseB, out ClaseC> > = mutableListOf()
它實際上不是HijoA類的超級型別,因為out對契約的限制比HijoA類簽名的定義要大。
在這種情況下,你不能使用out,因為你是作為函式引數接收泛型的。如果你從不回傳這些值,你可以呼叫它們in,但是你又一次通過 contravariance 限制了契約,只允許下游的實作。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/328692.html
標籤:
