首页 > 解决方案 > Kotlin 在类层次结构中静态和非静态访问成员的方法是什么?

问题描述

我想在 Kotlin 中实现以下设计:

类层次结构的重要大小,共享一个公共根(我们称之为Base)。这个层次结构的所有类都有一些参数,它们应该可以静态访问(因为它们在工厂方法中需要)和动态(因为它们需要从外部代码中访问)。另外,由于我将创建这些类的大量实例,因此我想避免为每个实例实例化一个列表/属性集。

这是我能够放在一起的东西,它有效,但感觉真的很难看。

abstract class Base {
    open val params: List<Int> get() = Companion.params

    companion object : BaseCompanion()
}
abstract class BaseCompanion {
    open val params: List<Int> = emptyList<Int>()
}

class A: Base() {
    override val params: List<Int> get() = Companion.params

    companion object : BaseCompanion() {
        override val params: List<Int> = listOf(1, 3)
    }
}

感觉非常笨重的部分是每个继承自的类Base都必须:

有没有更好、更 Kotlin 的方式来做到这一点?

标签: inheritancekotlinstatic

解决方案


反过来怎么做,即从外部传递列表,例如:

abstract class Base(val params : List<Int>)

class A(params : List<Int>) : Base(params)

在对象创建方面,只需保留该“静态”列表并将其传递给您新创建的对象:

val staticParams = listOf(1, 3)
val oneOfManyA = A(staticParams)

如果您仍然想要在不传递静态参数和/或将它们保存在同伴中的情况下单独实例化的外观和感觉A,您仍然可以使用invoke-operator 来实现:

class A(params : List<Int>) : Base(params) {
  companion object {
    private val staticParams = listOf(1, 3)
    operator fun invoke() = A(staticParams)
  }
}

现在您可以按如下方式调用它,它将使用伴随对象的静态参数进行实例化:

A()

另请注意:只要您按原样传递列表,所有列表共享相同的内容(因为您只传递原始列表的引用)......如果您使用类似的东西staticParams.toList(),基本上创建自己的新列表而是通过了,它与原始列表断开连接。

根据您真正想做的事情,扩展属性也可能符合目的(这不是建议,只是解决问题的一种方法;-)):

abstract class Base
class A : Base()


val A.params
      get() = listOf(1, 3)

// or:
val staticParams = listOf(1, 3)
val A.params
      get() = staticParams

这样您就可以节省companion object等,并将您的静态列表直接附加到A. 这有其自身的缺点,但也可能是一个解决方案......


推荐阅读