【发布时间】:2014-08-20 06:50:52
【问题描述】:
在 Cay Horstmann 的《不耐烦的 Scala》一书中,在第 5 章练习 8 中,有这样一个问题:
//Make a class Car with read-only properties for manufacturer, model name,
//and model year, and a read-write property for the license plate. Supply four
// constructors. All require the manufacturer and model name. Optionally,
//model year and license plate can also be specified in the constructor. If not,
//the model year is set to -1 and the license plate to the empty string. Which
//constructor are you choosing as the primary constructor? Why?
所以我编写了这个类:
case class Car(val manufacturer: String, val modelName: String,
val modelYear: Int, var licensePlate : String = "") {
def this(manufacturer: String, modelName: String, licensePlate: String) {
this(manufacturer, modelName, -1, licensePlate)
}
def this(manufacturer: String, modelName: String, modelYear: Int) {
特别是这部分:
this(manufacturer, modelName, modelYear)
}
def this(manufacturer: String, modelName: String) {
this(manufacturer, modelName, -1)
}
}
编译器报错:
<console>:14: error: called constructor's definition must precede calling constructor's definition
this(manufacturer, modelName, modelYear)
^
当我在主构造函数中将车牌的默认值作为空字符串提供时它为什么会抱怨,并且它肯定是首先定义的??
如果我这样做,错误就会消失:
this(manufacturer, modelName, modelYear, "")
或者如果我让类主构造函数没有 licensePlate 的默认值(当然在此过程中调整其他辅助构造函数调用)。
请注意,该问题专门针对 4 个构造函数,因此可以像这样调用实例创建:
new Car("Honda", "City", 2010, "ABC-123")
new Car("Honda", "City")
new Car("Honda", "City", "ABC-123")
new Car("Honda", "City", 2010)
提前感谢那些能够阐明这个问题的人。
====
感谢 Ende Neu 和 Kigyo 的回答,这看起来是完美的解决方案(删除递归构造函数):
case class Car(val manufacturer: String, val modelName: String,
val modelYear: Int = -1, var licensePlate : String = "") {
def this(manufacturer: String, modelName: String, licensePlate: String) {
this(manufacturer, modelName, -1, licensePlate)
}
<< removed constructors here >>
}
Console println new Car("Honda", "City", 2010, "ABC-123")
Console println new Car("Honda", "City")
Console println new Car("Honda", "City", "ABC-123")
Console println new Car("Honda", "City", 2010)
【问题讨论】:
-
如果你现在在这条路上,你也可以有一个
modelYear的默认值。然后你也可以删除最后一个构造函数。我以为你的想法是有四个构造函数。 :) -
我们是完美主义者吗,Kigyo?我再次更新了它(见上文)。现在这不是那么完美。即使我在主构造函数中有一个默认值,我仍然在辅助构造函数中将 -1 传递给模型年份。这可以进一步改进吗?
-
在这种情况下我没有发现任何改进。 :(
标签: scala