【问题标题】:Map with initial values in abstract class抽象类中具有初始值的映射
【发布时间】:2020-11-25 10:10:15
【问题描述】:

我有一个抽象类,它包含一些默认值,如下所示

BaseRequest.kt

abstract class BaseRequest {

    abstract val route: String

    /** Initially, all requests contain the route param, that's why it has to be added for all requests */
    val baseMap: Map<String, String> by lazy { mapOf("route" to route) }

    abstract fun toMap(): Map<String, String>
}

现在,对于所有子类,我需要扩展BaseRequest 类的任何人来覆盖toMap() 函数并返回一个初始值为route 的映射,该映射在基类中初始化。

我的意思是,一旦用户覆盖地图并用任何值填充它,我就会为这些值添加一个默认值。

例如

ItemRequest.kt

class ItemsRequest: BaseRequest() {

    override val route: String = "items"

    override fun toMap(): Map<String, String>  = mapOf("id" to "7")

}

对于ItemsRequest 类,我需要toMap() 函数返回的映射具有id 以及默认的route,而无需在每个子类中手动添加它。

这可能吗?

【问题讨论】:

  • 在您的第一个代码 sn-p 中,ROUTE 是否只是代码中实际值的占位符?
  • @ChrisGong 是的,为了清楚起见,我对其进行了编辑
  • 我们是否可以假设 toMap 方法中的映射中的任何键值对都不会重新定义/覆盖 baseMap 中的键值对?
  • 基本上,baseMap 试图实现我正在尝试做的事情,但它没有奏效。因此,可以根据建议的方法对其进行修改或消除。

标签: java kotlin


【解决方案1】:

我相信您可以简单地将子类打算返回的映射与超类中的baseMap 变量结合起来。由于您从您的 cmets 中说可以修改原始 baseMap,您可以简单地使用 baseMap 和您希望特定子类返回的任何其他映射之间的加号操作,

override fun toMap(): Map<String, String>  = baseMap + mapOf("id" to "7")

注意baseMap 如何位于加号操作的左侧。在这种情况下,如果 baseMap 和加号操作右侧的映射中都存在任何键,则从 toMap 返回的最终映射将仅包含加号操作右侧的映射中的值两个地图共有的键。如果您希望 baseMap 键值对优先并始终从任何从任何子类的 toMap 方法返回的任何映射中返回,则将 baseMap 放在加号操作的右侧,如下所示,

override fun toMap(): Map<String, String>  = mapOf("id" to "7") + baseMap

但是,假设您希望每个子类的 toMap 实现至少返回 baseMap,那么为每个覆盖它的子类不断地反复写入 baseMap + ...... + baseMap 可能是非常多余的toMap 方法。因此,我的建议是使父类中的toMap 函数成为非抽象函数,并定义一个不同的抽象函数,仅用于将映射自定义返回到从父类派生的类。这就是我的意思,

abstract class BaseRequest {

    abstract val route: String

    /** Initially, all requests contain the route param, that's why it has to be added for all requests */
    val baseMap: Map<String, String> by lazy { mapOf("route" to route) }

    abstract fun subMap(): Map<String, String>

    // again, up to you with how you want to combine the two maps, 
    // assuming you are okay with key-value pairs being overwritten by one of the maps, 
    // the plus operation is fine
    fun toMap(): Map<String, String> = baseMap + subMap()
}

class ItemsRequest: BaseRequest() {

    override val route: String = "items"

    override fun subMap(): Map<String, String>  = mapOf("id" to "7")

}

请注意,subMap 函数也可以是一个变量,就像您如何处理 route 变量一样。现在,BaseRequest 的每个派生类的 toMap 函数将返回 baseMapsubMap() 的组合。

【讨论】:

  • 非常感谢,subMap 方法正是我想要的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多