Scala继承中父类默认参数

9

我有一个带有默认参数值的抽象类。 我不想在所有可能的实现类的构造函数中重复使用默认值。

abstract class Place(val place: String = "World")
class Message(val message: String = "Hello", p: String) extends Place(p) {
    override def toString = s"$message $place"
}

What I want to get

new Message("Hi", "Universe") = "Hi Universe" // Ok
new Message("Hi") = "Hi World" // Doesn't work, second parameter is required
new Message() = "Hello World" // Doesn't work, second parameter is required

我曾考虑使用忽略第二个参数的辅助构造函数,但它并没有帮助,因为你无法在主构造函数之外调用超级构造函数。

我想知道如何做到这一点,或者为什么不可能做到。我不想寻找解决方法,比如不使用继承。

2个回答

3

很抱歉,这是不可能的。简单来说,你正在向Place构造函数传递一个值,因此它不会使用默认值,无论其值是什么。如果您不介意使用var而不是val,则有一种适用于您三种情况的变体:

abstract class Place(var place: String = "World")
class Message(val message: String = "Hello") extends Place()
{
   def this(message: String, place: String) = {
      this(message)
      this.place = place
   }
   override def toString = s"$message $place"
}

在Scala中,构造函数有点混乱(个人看法)。有时候更好的答案是只使用伴生对象上的工厂apply()方法,这样更加灵活。


1
您可以更优雅地重用默认值:
object Place {
  val defaultPlace = "World"
}
abstract class Place(val place: String = Place.defaultPlace)
class Message(val message: String = "Hello", p: String = Place.defaultPlace) extends Place(p) {
  override def toString = s"$message $place"
}

这里有三个对象需要处理(对象,抽象和类),不能封装起来。特别是不要将对象和抽象具有相同的名称视为功劳。类Message必须知道对象Place,因此使用它需要更多的连接,如果这有任何意义的话。抽象和具体应该处理所有这些。 - Drew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接