inheritance - 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
都必须:
- 有一个从 BaseCompanion 继承的伴生对象(这里实际上不需要它,但我需要一些东西来传递给通用工厂方法)。
- 在其中包含他们自己的静态变量参数。
- 覆盖 params 属性,使其从自己的伴生对象返回值。
有没有更好、更 Kotlin 的方式来做到这一点?
解决方案
反过来怎么做,即从外部传递列表,例如:
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
. 这有其自身的缺点,但也可能是一个解决方案......
推荐阅读
- javascript - Vusual 工作室代码 @flow create-react-app
- java - 布尔值没有被返回?
- c# - 比较元组
- python - 将 Django 从 windows 转移到 ubuntu
- java - 试图让 Tess4J 工作
- java - 如何制作程序来打印系列:1,12,123...12345678910,1234567891011...& 等等到第 n 个学期?
- python - 全连接层上的爆炸梯度
- com - VB6:某些短语的语音转文本
- c - 如何在 C 中的数组中拥有变量索引
- django - 如何使用 update_or_create() 和 F() 在 Django 中创建新记录?