在下面的代码中,我想设置对类实例的引用,以便静态函数可以返回对该实例的引用:
open class TestRunner {
init {
instance = this
}
companion object {
private lateinit var instance: TestRunner
fun addTestSetups(vararg testSetups: () -> TestSetup): TestRunner {
for (setup in testSetups) {
testsSetups.add(setup)
}
return instance
}
}
}
但是不允许设置instance = this
。如何在保持类为单例状态的同时从函数返回该类的实例?
答案 0 :(得分:0)
这似乎有效。代替保留一个变量来保存对该类的引用,只需引用该类的名称就足够了。但是,要从函数返回类的实例,返回类型必须为Companion:
open class TestRunner {
companion object {
fun addTestSetups(vararg testSetups: () -> TestSetup): Companion {
for (setup in testSetups) {
testsSetups.add(setup)
}
return TestRunner
}
}
}
这不是真正的单例,因为如果这样做,您仍然可以创建新实例:
val testRunner = TestRunner()
但是,如果您从不创建实例,而仅静态地引用函数,则它的行为就像单例一样,并且随行对象中任何私有变量的状态仍将保持。
更新:
我在Android开发人员网站上遇到了这段代码,该代码显示了一个设置为单例的类的示例:
class StockLiveData(symbol: String) : LiveData<BigDecimal>() {
private val stockManager: StockManager = StockManager(symbol)
private val listener = { price: BigDecimal ->
value = price
}
override fun onActive() {
stockManager.requestPriceUpdates(listener)
}
override fun onInactive() {
stockManager.removeUpdates(listener)
}
companion object {
private lateinit var sInstance: StockLiveData
@MainThread
fun get(symbol: String): StockLiveData {
sInstance = if (::sInstance.isInitialized) sInstance else StockLiveData(symbol)
return sInstance
}
}
}
但是应该指出的是,该示例需要一些函数,这些函数需要返回一个实例,以首先检查是否设置了实例变量,如果未设置,则创建一个新实例。我不确定这样做的目的是什么,因为调用已有实例的函数。那么,为什么还要创建一个新实例呢?似乎没有任何意义。
答案 1 :(得分:0)
如果我说对了,您想要这样的东西:
abstract class TestRunner {
companion object : TestRunner()
}
答案 2 :(得分:0)
object
是单例,而不是其内部定义的类。伴随对象具有额外的便利,允许您使用该外部类的名称来调用它。但是否则它不共享任何层次结构。
要使您的类可继承,您不能在伴随对象中定义函数。但是您可以将类抽象化,因此除非进行子类化,否则无法实例化该类。然后使您的伴随对象扩展抽象类,以便它将所有这些功能都可用。
abstract class TestRunner{
open fun addTestSetups(vararg testSetups: () -> TestSetup): TestRunner{
//...
return this
}
companion object: TestRunner()
}
用法:
TestRunner.addTestSetups(someTestSetup)
请注意,您的单例不是TestRunner的实例。它是TestRunner子类的单例实例。但是,由于您没有定义任何额外的功能并且什么也没有覆盖,因此它的行为完全类似于TestRunner。
如果您想要一个子类:
abstract class ExtendedTestRunner: TestRunner() {
fun someOtherFunction() {}
companion object: ExtendedTestRunner()
}
同伴并没有被子类化,但是它们的抽象父母可以被归类。