[英]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.