工厂对象和案例类

时间:2013-07-04 09:15:23

标签: scala factory case-class

我想用定义的apply方法创建工厂对象,这将创建基础案例类 - 这是一个示例代码

object DeptEntry {  
  def apply(url: String, fullName: String, address: String, city: String): DeptEntry = {
    new DeptEntry(url.toLowerCase, fullName.toLowerCase, address.toLowerCase, city.toLowerCase)
  }
}

case class DeptEntry private(url: String, fullName: String, address: String, city: String) {
}

问题是对象和case类的构造函数中的apply方法具有相同的参数列表。 所以编译器给了我这个错误:

method apply is defined twice
  conflicting symbols both originated in file 'DeptEntry.scala'
case class DeptEntry private(url: String, fullName: String,
       ^

这个问题是否有解决方法?

非常感谢

4 个答案:

答案 0 :(得分:3)

声明案例类abstract

object DeptEntry {  
  def apply(url: String, fullName: String, address: String, city: String): DeptEntry = {
    new DeptEntry(url.toLowerCase, fullName.toLowerCase, address.toLowerCase, city.toLowerCase) {}
  }
}

abstract case class DeptEntry private(url: String, fullName: String, address: String, city: String) {
}

根据Iulian Dragos commenting on SI-844

的说法

答案 1 :(得分:0)

您可以将DeptEntry设为“普通”(非案例类)类。或者,您可以在Object中使用具有不同名称的Method。 (例如DeptEntry.lowerCase(...))

答案 2 :(得分:0)

当您创建case class时,Scala编译器会自动为您生成一个带有apply方法的伴随对象。此apply方法与case类的构造函数具有相同的参数。这就是您遇到此编译器错误的原因。你不能覆盖它的事实确保了这样的东西:

val inputUrl = "MyUrl://blabla"
val DeptEntry(outputUrl, _, _, _) = DeptEntry(inputUrl, "", "", "")
outputUrl == inputUrl 

尝试从类定义中删除case并自行编写随播广告对象的apply(如果需要提取,则为unapply)(toString,{{1}如果需要,可以在类本身中使用equals

答案 3 :(得分:0)

一种可能性是从您的用户隐藏(一点点)该类:

sealed trait DeptEntry
object DeptEntry {
  def apply(url: String, fullName: String,
            address: String, city: String): DeptEntry = // ...

  case class Value protected[DeptEntry](
    url: String, fullName: String, address: String, city: String
  )
}

这种方式没有冲突,如果需要,您仍然可以在DeptEntry.Value上进行模式匹配。如果此解决方案方便与否,这取决于您的用例。如果您希望特征具有正确的val s,则可以将其声明为

sealed trait DeptEntry {
    val url: String
    val fullName: String
    val address: String
    val city: String
}

case class中的字段将覆盖它们。