這里 a 有一個泛型型別,但我不明白為什么即使我沒有使型別 T 協變,我也可以將 Player 的子類添加到我的泛型類和具有上限 T 的函式中: Player; 那么為什么在不使用 out 關鍵字的情況下保留子型別?因此,我可以 - 錯誤地 - 將 BaseballPlayer 和 GamesPlayer 添加到足球隊。1
class Team<T : Player>(val name: String, private val players: MutableList<T>) {
fun addPlayers(player: T) {
if (players.contains(player)) {
println("Player: ${(player as Player).name} is already in the team.")
} else {
players.add(player)
println("Player: {(player as Player).name} was added to the team.")
}
}
}
open class Player(open val name: String)
data class FootballPlayer(override val name: String) : Player(name)
data class BaseballPlayer(override val name: String) : Player(name)
data class GamesPlayer(override val name: String) : Player(name)
val footballTeam = Team<Player>(
"Football Team",
mutableListOf(FootballPlayer("Player 1"), FootballPlayer("Player 2"))
)
val baseballPlayer = BaseballPlayer("Baseball Player")
val footballPlayer = FootballPlayer("Football Player")
val gamesPlayer = GamesPlayer("Games Player")
footballTeam.addPlayers(baseballPlayer)
footballTeam.addPlayers(footballPlayer)
footballTeam.addPlayers(gamesPlayer)
uj5u.com熱心網友回復:
您在此行定義的可變串列:
mutableListOf(FootballPlayer("Player 1"), FootballPlayer("Player 2"))
不是一個MutableList<FootballPlayer>。它是 a MutableList<Player>,因為您沒有指定它的型別,所以編譯器使用型別推斷來假設您希望 aMutableList<Player>適合建構式的建構式引數Team<Player>。
因此,將任何型別的Player放入 a都是有效的MutableList<Player>,因為它只能回傳型別的專案Player。它仍然是型別安全的。
如果你已經明確了型別,那將是一個編譯錯誤:
val footballTeam = Team<Player>(
"Football Team",
mutableListOf<FootballPlayer>(FootballPlayer("Player 1"), FootballPlayer("Player 2"))
//error, expected MutableList<Player>
)
或者,如果您從 Team 建構式中省略了型別,它會假設您想要 aTeam<FootballPlayer>并且在嘗試添加其他型別的玩家時會出錯:
val footballTeam = Team(
"Football Team",
mutableListOf(FootballPlayer("Player 1"), FootballPlayer("Player 2"))
)
// ^^ is a Team<FootballPlayer> because of type inferrence.
footballTeam.addPlayers(BaseballPlayer("Foo")) // error, expected FootballPlayer
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/483540.html
上一篇:帶有泛型的Kotlin中綴函式
下一篇:將任何setter作為引數的方法
