假设我想在 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)构造函数)。
您似乎正在寻找的是工厂模式:
- 从
XMLObject
中删除构造函数 - 如果需要,可以向
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/