Kotlin在抽象类中调用伴随对象

时间:2018-04-06 21:57:03

标签: java kotlin

我有一个类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的代码在派生类中是相同的,所以我想避免在我创建的每个类中重新创建功能。

3 个答案:

答案 0 :(得分:1)

age   job       month   predict
33   blue       apr       0
56   admin      jun       0
37   tech       aug       0
76   retired    jun       1
56   service    may       0

可能有用,但可能需要使用不安全的反射。这取决于你在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

答案 1 :(得分:1)

如果初始化逻辑相同且基于Base类中指定的功能,您也可以这样做:

abstract class Base() {

    protected fun init(): Base {
        // do the initialization
        return this
    }
}

class A : Base() {
    companion object {
        fun create() = A().init() as A
    }
}

答案 2 :(得分:0)

我假设您的类共享一个具有相同参数列表的构造函数。 然后你可以做的是定义一个特征

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() 来返回正确的类型