Class的默认构造函数

时间:2014-10-30 21:16:51

标签: scala

我在Scala中有这样的课程:

abstract class ErrorMessages(val message: String, val publicMessage: String, val objectData: Option[Object], val backtrace: Exception)

我使用战利品作为子类,例如

case class MyError(override val message: String, override val publicMessage: String, override val objectData: Option[Object], override val backtrace: Exception) extends ErrorMessages(message, publicMessage, objectData, backtrace)

我在这里的问题是,我可以更轻松地做case class MyError(...) extends ErrorMessages(...)或者simulary,以简化创建我的errpr的新实例所需的代码。

1 个答案:

答案 0 :(得分:0)

您可以将所有构造函数参数聚合到一个案例类中,然后将此案例类传递给构造函数。例如:

case class ErrorData(message:String, publicMessage:String, objectData:Option[Object], backtrace:Exception)

abstract class ErrorMessages(data:ErrorData)

case class MyError(data:ErrorData) extends ErrorMessages(data)

这可能需要一些改进。例如,您可能希望通过ErrorData访问ErrorMessages的组件:

abstract class ErrorMessages(data:ErrorData) {
  def message:String = data.message
  def publicMessage:String = data.publicMessage
  // ...
}

通过这种方式,MyError还会继承允许直接访问messagepublicMessageobjectData等的方法。有效地,{{1}的存在隐藏在外面的世界。它只是一个用于创建ErrorData子类型实例的实用程序。但是,这也需要您重新引入示例中的ErrorMessages修饰符。

这是另一种设计:

也许你也想完全跳过构造函数。您可以通过使override的组件抽象来实现。例如:

ErrorMessages

在这种情况下,您可以像在示例中一样实现abstract class ErrorMessages { // could also be a trait now def message:String def publicMessage:String def objectData:Option[Object] // ... } 案例类,除了MyError修饰符。这将完全绕过构造函数参数的传递,并作为额外的奖励,向实现者开放他如何实现这些抽象方法。 (例如,您可以拥有一个子类型实现,其公共消息始终与消息相同。)

最后,您可以发挥创意并将这些策略结合起来。也许您不希望将所有构造函数参数集成到单个大案例类中,但只是其中一些以主题方式组合在一起。当你有很多构造函数参数时,有时这可能表明你需要更多的综合数据类型。例如:

override

或者你可以两种方式混合:

case class Message(internalText:String, publicText:String)
case class ErrorOrigin(objectData:Option[Object], backtrace:Exception)

trait ErrorMessages { // you can use the constructor approach or abstract members, as shown here
  def message:Message
  def origin:ErrorOrigin

  def internalMessageText = message internalText
  def publicMessageText = message publicText
  def objectData = origin objectData
  def backtrace = origin backTrace
}

case class MyErrorMessage(message:Message, origin:ErrorOrigin) extends ErrorMessages

不确定这种分离是否适合您,或者这些类型和成员名称是否适用于您的情况。但我希望你能看到这样的图片:有一些值得注意的替代方案,你可以随意使用它们并选择最合适的选择。

但是,没有办法省略继承的构造函数参数的传递。拥有一个文字abstract class ErrorMessages(val origin:ErrorOrigin) { def message:Message def internalMessageText = message internalText // ... } case class MyErrorMessage(message:Message, override val origin:ErrorOrigin) 构造会更好,其中Scala编译器适合所有与子类型具有相同名称的超类型构造函数参数,但这样的特征不存在。< / p>