Inheritance Kotlin以什么方式静态和非静态地访问类层次结构中的成员?

Inheritance Kotlin以什么方式静态和非静态地访问类层次结构中的成员?,inheritance,kotlin,static,Inheritance,Kotlin,Static,我想在Kotlin中实现以下设计: 类层次结构的非平凡大小,共享一个公共根(我们称之为Base)。这个层次结构的所有类都有一些参数,这些参数应该可以静态访问(因为它们在工厂方法中需要)和动态访问(因为它们需要从外部代码中访问)。另外,由于我将创建这些类的许多实例,因此我希望避免为每个实例实例化一个属性列表/属性集 这是我能拼凑出来的东西,很管用,但感觉很难看 abstract class Base { open val params: List<Int> get() = Co

我想在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)
    }
}
抽象类基类{
打开val params:List get()=Companion.params
companion对象:BaseCompanion()
}
抽象类基类{
open val params:List=emptyList()
}
A类:Base(){
覆盖val-params:List get()=Companion.params
companion对象:BaseCompanion(){
覆盖val参数:List=listOf(1,3)
}
}
感觉非常笨拙的部分是,从
Base
继承的每个类都必须:

  • 有一个从BaseCompanion继承的companion对象(这里实际上不需要它,但我需要一些东西传递给泛型工厂方法)
  • 在其中包含它们自己的静态变量参数
  • 重写params属性,使其从自己的伴生对象返回值

有没有更好的、更具科特林特色的方法呢?

换一种方法,也就是从外部传递列表,例如:

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

class A(params : List<Int>) : Base(params)
如果您仍然希望单独实例化
A
,而不传递静态参数和/或将它们保存在伴奏中,您仍然可以使用
invoke
-操作符来实现这一点:

class A(params : List<Int>) : Base(params) {
  companion object {
    private val staticParams = listOf(1, 3)
    operator fun invoke() = A(staticParams)
  }
}
另外请注意:只要您按原样传递列表,所有列表共享相同的内容(因为您只传递原始列表的引用)。。。如果您想使用类似于
staticParams.toList()
的东西,您基本上会创建自己的新列表,而该列表将被传递,它与原始列表断开连接

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


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

我必须说,这是对我原来的解决方案的改进,谢谢。看起来好多了。构造函数有一个总是接收相同值的参数,这有点让人感觉不对劲,但因为它只从伴随对象中的invoke函数调用,所以它可能被算作一个内部构造(如果您将默认构造函数设置为受保护的)。酷。如果有人有其他想法,我还是会把问题留待讨论。@Vojtěchěerný这取决于你如何使用它。。。我认为,在需要具有自己列表的对象时,保持构造函数可见更有意义。。。但如果它真的是静态的,那么将其私有化可能更有意义。。。如果你所说的“把问题留着”,你的意思是:还不接受答案,我同意。。。刚刚添加了另一个使用扩展属性的变体。。。也许你更喜欢这个。。。
class A(params : List<Int>) : Base(params) {
  companion object {
    private val staticParams = listOf(1, 3)
    operator fun invoke() = A(staticParams)
  }
}
A()
abstract class Base
class A : Base()


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

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