Here a have a generic type, but I don't understand why even though I didn't made the type T covariant, I can add subclasses of Player to my generics class and function which has an upper bound T: Player; so why is the subtyping preserved without using the out keyword; and because of this I can - wrongly- add a BaseballPlayer and GamesPlayer to a football team. 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)