Scala:通过提取参数的替代构造函数构造基类

时间:2016-11-23 14:14:15

标签: scala

我们说我有以下等级:

abstract class A(val x: Int, val y: String)
class B(override val x: Int, override val y: String, val z: Int) extends A(x,y)

现在我想从配置对象初始化值,但我希望实际值是原始值。 如果我只在B中进行配置,那么我会做类似的事情:

class B(override val x: Int, override val y: String, val z: Int) extends A(x,y)
def this(conf: Conf) {
     this(conf.get("x"), conf.get("y"), conf.get("z"))
}

但我希望能够在A中做同样的事情。 如果我添加:

abstract class A(val x: Int, val y: String)
this(conf: Conf) {
    this(conf.get("x"), conf.get("y))
}

我无法定义B(我没有在B默认构造函数中使用conf)。

修改

为了更清楚: 我使用的用例是生成适当B(有大量子类)的工厂。它通过以下方式实现:

def getElement(elemType: String, conf: Conf): A = {
   elemType match {
       case "B" => new B(conf)
   }
}

目前,我有一个配套对象:

object B {
   def apply(conf: conf) = B(conf.getx(), conf.gety(), ...)
}

问题是,当我需要向父A添加一个新元素时,我需要去更改每个子节点,并且我有相同的代码conf.getx(),conf.gety()等。

理想情况下,我希望B构造函数能够执行以下操作:

class B(conf: Conf) extends A(conf)

但我无法做到这一点,因为这会让他成为B的成员。

2 个答案:

答案 0 :(得分:0)

您还可以使用companion objects来定义替代构造函数:

case object A {

  def apply(conf: Conf): A = new A(conf.get("x"), conf.get("y"))
}

case object B {

  def apply(conf: Conf): B = new B(conf.get("x"), conf.get("y"), conf.get("z"))
}

答案 1 :(得分:0)

环顾四周后,我发现this(也指向this)和this。这三个人基本上都说了以下几点:

如果我们使用不带val或var的参数,并且只在构造函数中引用它,那么 NOT 会成为成员。

这意味着以下解决方案可行:

abstract class A(conf: Conf) {
  val x = conf.getX()
  val y = conf.getY()
}

class B(conf: Conf) extends A(conf) {
  val z = conf.getZ()
}

将干净利落地提供所需的行为。