如何从Scala中的派生类辅助构造函数调用辅助基类构造函数?

时间:2014-11-29 21:07:23

标签: scala constructor overloading base-class

您可以通过派生类主构造函数调用基类中的辅助构造函数:

class Base(n:Int) {
    def this(n:Int, i:Int) = {
        this(n)
        println(i)
    }
}

class Derived(n:Int, i:Int) extends Base(n, i)

是否有从辅助派生类构造函数调用辅助基类构造函数的语法?这不起作用:

class Derived2(n:Int) extends Base(n) {
    def this(n:Int, i:Int) = {
        super.this(n, i) // Can't do this
        println(i)
    }
}

在其他语言中,你可以这样做,但你必须先调用基类构造函数,这就是我在这里尝试的原因。

请注意,我正在寻找调用的语法,而不是寻找相同结果的替代方法。

1 个答案:

答案 0 :(得分:4)

在Scala中,无论如何都必须通过默认构造函数,这会强制您在类实例化中选择一个超级构造。这基本上是你在java方面要做的事情:

public class Derived2 extends Base {
    public Derived2(int n, int i) {
        super(n, i);
    }
    public Derived2(int n) {
        super(n);
    }
}

因为在Scala中你必须经历默认构造函数,所以这就是:

public class Derived2 extends Base {
    public Derived2(int n, int i) {
        this(n);
        super(n, i); //does not compile
    }
    public Derived2(int n) {
        super(n);
    }
}

因此,正如在Java中一样,您只能将superthis作为构造函数实现的第一行。由于Scala强制调用默认构造函数,因此只能使用Base构造函数的一个实现。

没有解决方法,因为这不是真正教条主义的Scala。我建议你在这里改变你的设计。 Scala中的继承通常通过特征来完成,而不是通过类或抽象类来完成。

以下是使用特征的替代方案:

  trait Base2 {
    val a:Int
  }

  class Derived3(n: Int) extends Base2 {

    val a = n

    def this(n: Int, i: Int) = {
      this(n)
    }
  }