我在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的新实例所需的代码。
答案 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
还会继承允许直接访问message
,publicMessage
,objectData
等的方法。有效地,{{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>