![](/img/trans.png)
[英]Is there a way to share data between an abstract class and it's implementation classes without using companion object in Kotlin
[英]Kotlin Calling Companion Object in Abstract Class
我有一个类Base
是一个抽象类,定义为:
abstract class Base() {}
我想从这个基类创建一些派生类:
class A : Base() {}
class B : Base() {}
class C : Base() {}
我希望能够调用一个通用函数create
来执行一些初始化工作并返回指定的派生类(例如A
)。 例如,类似以下的内容将是理想的:
val a = A.create() // `a` now holds an instance of `A`.
val b = B.create()
val c = C.create()
最初我尝试在抽象类中使用伴随对象作为一种静态函数:
abstract class Base {
companion object {
fun create() : Base {
// Do some initialization and return the derived class
// of the object. Obviously I can't return `Base` as I've
// indicated above since it is an abstract class. This is
// what I'm confused about: How do I return a copy of the
// _derived_ class here? Is this impossible? I think it
// might be...
return Base() // <-- This doesn't work. What should be returned?
}
}
}
然后在派生类中:
class A : Base() {
companion object {
fun create() : A = Base.create()
}
}
这行不通,原因很明显。 即,我无法返回抽象类Base
的实例。 有没有一种简单的方法来完成var a = A.create()
范式? create
的代码在派生类中是相同的,所以我想避免在我创建的每个类中重新创建功能。
如果初始化逻辑相同并且基于Base
类中指定的功能,您也可以这样做:
abstract class Base() {
protected fun init(): Base {
// do the initialization
return this
}
}
class A : Base() {
companion object {
fun create() = A().init() as A
}
}
abstract class Base {
companion object {
inline fun <reified T : Base> create() : T {
// you can use T::class here
}
}
}
class A : Base() {
companion object {
fun create() : A = Base.create() // inferred to Base.create<A>()
}
}
可能工作,但可能需要使用不安全的反射。 这取决于您在create
究竟想做什么......更好的做法是将类之间的任何不同作为函数传递,例如
abstract class Base {
companion object {
inline fun <reified T : Base> create(f: () -> T) : T {
val instance = f()
// do something
return instance // or something created from it
}
}
}
class A : Base() {
companion object {
fun create() : A = Base.create { A() }
}
}
我假设您的类共享一个具有相同参数列表的构造函数。 然后你可以做的是定义一个特征
trait Instantiation[K] {
def newWith(args):K
}
让你的课程实现这个
class A implements Instantiation[A] {
override def newWith(args):A
}
class B implements Instantiation[B] {
override def newWith(args):B
}
class C implements Instantiation[C] {
override def newWith(args):C
}
现在在共享逻辑中,您可以调用 newWith() 来返回正确的类型
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.