有人能给我解释一下继承在Kotlin中是如何工作的吗?我在Kotlin的继承中挣扎,似乎无法完成我在Java中所知道的简单任务。
在Java中,我们可以这样做:
class Base {...}
class AClass extends Base {...}
class BClass extends Base {...}
字符串
以及一个这样做的服务:
Base myMethod(...) {
return new AClass() //or new BClass()
}
型
因为AClass是Base,BClass也是Base。
当我在Kotlin中尝试相同的操作时,我得到了一条错误消息,告诉我在尝试返回AClass或BClass对象的地方需要一个Base对象。
类型不匹配。必需:找到的基:AClass?
那么,Kotlin是如何实现这样简单的事情的呢?
编辑:Kotlin类
sealed class GameObject {
abstract val objectId: String
abstract val objectName: String
}
sealed class Resource(
override val objectId: String,
override val objectName: String,
open val resourceType : ResourceType
): GameObject() {
abstract val usageEffects: List<UseEffect>
abstract val eolEffects: List<DiscardEffect>
abstract val recipes: List<Recipe>
abstract val providedEnergy: Int
abstract val neededEnergy: Int
}
data class BaseResource(
override val resourceType: ResourceType,
override val usageEffects: List<UseEffect> = emptyList(),
override val eolEffects: List<DiscardEffect> = emptyList(),
override val recipes: List<Recipe> = emptyList(),
override val providedEnergy: Int = 0,
override val neededEnergy: Int = 0,
): Resource("RES", "RES", resourceType)
data class ProductionFactor(
override val resourceType: ResourceType,
override val usageEffects: List<UseEffect> = emptyList(),
override val eolEffects: List<DiscardEffect> = emptyList(),
override val recipes: List<Recipe> = emptyList(),
val productivity: Int = 1,
override val providedEnergy: Int = 0,
override val neededEnergy: Int = 0,
val combustibleTypes: List<ResourceType> = emptyList()
var combustibles: List<Resource> = mutableListOf()
): Resource("RES", "RES", resourceType)
型
这些是我与之斗争的一些对象。
现在的用例:所有的'Resource'对象(包括BaseResource和ProductionFactor)都存储在这个map中:
var resourcesMap: EnumMap<ResourceType, out Resource>
型
根据事件的不同,我想返回一个Resource对象的副本,它在这个map中存储为“value”(相对于“key”的ResourceType):
fun getCard(card: Card): GameObject? {
var gameObject: GameObject? = null
val type = card.cardType
when (type) {
CardType.TERRITORY -> {
val territoryCard = card as TerritoryCard
val territoryType = territoryCard.territory
gameObject = territoriesMap[territoryType]?.copy(objectId = card.cardId, objectName = card.cardName)
}
CardType.RESOURCE -> {
val resourceCard = card as ResourceCard
val resourceType = resourceCard.resource
when (val resource = resourcesMap[resourceType]) {
is BaseResource -> {
gameObject = resource.copy(objectId = card.cardId, objectName = card.cardName)
}
is ProductionFactor -> {
gameObject = resource.copy(objectId = card.cardId, objectName = card.cardName)
}
null -> println("Unknown type")
}
}
CardType.BUILDING -> {
val buildingCard = card as BuildingCard
val buildingType = buildingCard.building
gameObject = buildingsMap[buildingType]?.copy(objectId = card.cardId, objectName = card.cardName)
}
}
return gameObject
}
型
1条答案
按热度按时间h5qlskok1#
类型不匹配。必需:找到的基:AClass?
原因是,即使
AClass
是Base
的子类型,AClass?
也 * 不是 *Base
的子类型,因为AClass?
在其值的子集中包含null
,但Base
没有。resourcesMap.get(...)
(或resourcesMap[...]
)返回不能赋值给Resource
的Resource?
。如果您想将此表达式赋值给不可空变量,则可以在赋值后立即(除了可能导致崩溃的!!
之外)使用?: return ...
或?: throw ...
,具体取决于与您的情况相关的逻辑