【问题标题】:Scala: is it possible to override default case class constructor?Scala:是否可以覆盖默认案例类构造函数?
【发布时间】:2011-02-09 07:09:40
【问题描述】:

只是想知道这是否可能。 我真正想做的是检查并可能修改其中一个参数,然后再将其存储为 val。

或者,我可以使用重载并将默认构造函数设为私有。在这种情况下,我还想将伴随对象中的默认工厂构造函数设为私有,我该怎么做?

非常感谢。

亚当

编辑:好吧,我发现将默认构造函数设为私有也会使默认工厂构造函数私有,所以我有一个解决方案,但我仍然想知道默认构造函数是否可覆盖

【问题讨论】:

  • 为什么要这样做?案例类旨在用于定义代数数据类型,因此添加的构造函数会稍微改变调用者的参数。就验证参数而言,可以使用assertrequire 在主构造函数中完成。
  • @adam77 将您的初始陈述重新构建为一个问题,“我可以检查并可能修改[案例类参数]吗?”答案是肯定的。我刚刚发布了有关此处相关问题的详细信息:stackoverflow.com/a/25538287/501113

标签: scala scala-2.8


【解决方案1】:

您无法选择更改默认构造函数存储其参数的方式(例如,在参数存储为vals 之前修改参数),但如果参数错误,您可以选择抛出异常(这将在参数存储后发生)

case class Foo(x:Int){
    if (x<0) throw SomeException;
}

您还可以选择实现调用第一个构造函数的其他构造函数

case class Foo(x:Int){
     def this(x:Int,y:Int) = this(x+y)
}

但那些没有工厂方法。

您可以通过将其添加到伴随对象中轻松地自己创建工厂方法

object Foo{
     def apply(x:Int,y:Int) = new Foo(x,y)
}

还有比这更复杂的事情,你必须放弃案例类并自己实现它的部分:applyunapplyequalshashCode在 Scala 中编程讨论了如何完成所有这些工作,为 equalshashCode 提供了很好的公式。

【讨论】:

  • 可以在将参数存储到案例类之前安全地更改参数。而且你仍然可以在不放弃案例类的所有好处的情况下做很多更复杂的事情。我刚刚在另一个线程上详细说明了我的解决方案:stackoverflow.com/a/25538287/501113
【解决方案2】:

辅助 case 类构造函数的存在不会导致编译器在类的同伴中生成额外的工厂方法,因此您将无法获得 CaseClaseName(«secondary constructor parameter list»&gt;) 的便利来创建它们。您必须使用 new 关键字。

最好将您描述的那种逻辑放在伴随对象中的备用工厂方法中,并坚持使用主构造函数。

【讨论】:

    【解决方案3】:

    你可以重载构造函数。它与 C++ 或 Java 中的相同。只需创建另一个构造函数。

    class Foo( _input:Int ){
        def this() = this( 0 )
    }
    

    或者你可以看this SO 帖子。

    【讨论】:

    • 谢谢,但问题是覆盖而不是超载。
    • 没有构造函数可以被覆盖,因为它们一开始就没有被继承。
    【解决方案4】:

    您可以通过在伴随对象中编写自己的apply(用于工厂)和unapply(用于模式匹配)方法将常规类转换为伪案例类。或者,您可以简单地在案例类的伴随对象中编写一个命名工厂方法。

    【讨论】:

      猜你喜欢
      • 2017-11-10
      • 2014-01-09
      • 2015-02-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-01
      • 2020-08-26
      相关资源
      最近更新 更多