我读到在Kotlin中不能重写静态方法,所以我不确定这是否可能,但是不能这样做会导致大量重复的代码。在将companion object
移动到Parent
时,是否有任何方法可以实现相同的行为?这是我到目前为止写的
家长。kt
abstract class Parent {
protected val TAG = this::class.java.simpleName
}
兄弟。kt
class Brother: Parent() {
companion object {
@Volatile private var instance: Brother? = null
fun getInstance() = instance ?: synchronized(this) {
instance ?: Brother().also { instance = it }
}
}
}
妹妹。kt
class Sister: Parent() {
companion object {
@Volatile private var instance: Sister? = null
fun getInstance() = instance ?: synchronized(this) {
instance ?: Sister().also { instance = it }
}
}
}
main()
fun main() {
println("Hello, ${Brother.getInstance().TAG}")
println("Hello, ${Sister.getInstance().TAG}")
}
控制台输出:
你好,哥哥你好,妹妹
也许这对你想做的事情有用。
你可以为执行这种模式的对象创建一个超类:
open class SingletonAccessor<T: Any> (private val constructor: () -> T){
@Volatile private var instance: T? = null
fun getInstance() = instance ?: synchronized(this) {
instance ?: constructor().also { instance = it }
}
}
然后从您的实现类伴侣对象继承它:
class Brother private constructor(): Parent() {
companion object: SingletonAccessor<Brother>(::Brother)
}
class Sister private constructor(): Parent() {
companion object: SingletonAccessor<Sister>(::Sister)
}
此模式与简单地创建哥哥和妹妹object
s没有太大的不同,因为它们没有构造函数参数,但也许这只是一个简化的示例。
根据@Tenfour04的回答,我提出了另一种方法,将SingletonAccessor
合并到Parent
abstract class Parent<T>(private val constructor: () -> T) {
@Volatile private var instance: T? = null
protected val TAG = this::class.java.simpleName
fun getInstance() = instance ?: synchronized(this) {
instance ?: constructor().also { instance = it }
}
}
子节点的实现与之前相同。
让我知道这个答案是否可以进一步改进。特别是,我想在类声明class Parent<T: Parent>
中这样做,但这不会编译。是否有一种方法可以将类型参数限制为自身及其子类型?