scala - Scala 中重写和继承的辅助构造函数

标签 scala inheritance constructor coding-style

假设我想在 Scala 中表示一本 Book,它是直接从 XML 生成的。 我想要一个包装父类 XMLObject 来包含可以直接映射到 XML 或从 XML 直接映射的类。

下面是一个有效实现的示例,但我想知道为什么构造函数不能是抽象的,并且您不能使用 override 关键字,但是您仍然可以在子类中重新定义与其父类具有相同签名的构造函数,并让它按照您期望的方式工作。

这是否被认为是“糟糕的”编码实践?如果是,那么获得类似功能的更好方法是什么?

abstract class XMLObject {
  def toXML:Node
  def this(xml:Node) = this()
}

class Book(

  val author:String = "",
  val title:String = "",
  val genre:String = "",
  val price:Double = 0,
  val publishDate:Date = null,
  val description:String = "",
  val id:Int = 0

  ) extends XMLObject {

  override def toXML:Node =
    <book id="{id}">
      ...
    </book>

  def this(xml:Node) = {
    this(
      author = (xml \ "author").text,
      title = (xml \ "title").text,
      genre = (xml \ "genre").text,
      price = (xml \ "price").text.toDouble,
      publishDate = (new SimpleDateFormat("yyyy-MM-dd")).parse((xml \ "publish_date").text),
      description = (xml \ "description").text
    )
  }
}

使用示例:

val book = new Book(someXMLNode)

最佳答案

构造函数只能以以下形式调用:

new X(...)

这意味着您知道要创建的对象的运行时类型。意思覆盖在这里没有任何意义。例如,您仍然可以在抽象类中定义构造函数,但这是为了链接(在类构造函数中调用父类(super class)构造函数)。

您似乎正在寻找的是工厂模式:

  1. XMLObject 中删除构造函数
  2. 如果需要,可以向 XMLObject 的同伴添加一个函数,该函数根据您传入的 XML 决定要创建哪个子类。

例如:

object XMLObject {
  def apply(xml: Node) = xml match {
    case <book> _ </book> => new Book(xml)
    // ...
    case _ => sys.error("malformed element")
  }
}

关于scala - Scala 中重写和继承的辅助构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17072266/

相关文章:

c++ - 在派生类的构造函数体中调用基类构造函数

scala - 如何创建带有条件要求字段的 Play Framework 2.0 表单?

objective-c - 子类的sharedClient方法

java - 窃听了我自己的 If-Else 语句

c++ - 如何将基类更改为继承类?

C++虚方法的虚继承

C++ 错误 : no matching constructor for initialization of

scala - 按名称类型参数

scala - 如何通过apache Spark graphX获取SSSP实际路径?

scala - 为什么 scala 允许对字符串中的单引号进行转义?