Reputation: 43
I want to create factory object with apply method defined that would create underlying case class - here is a sample code
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) {
}
The problem is that apply method in the object and case class's constructor have the same parameter list. So compiler gives me this error:
method apply is defined twice
conflicting symbols both originated in file 'DeptEntry.scala'
case class DeptEntry private(url: String, fullName: String,
^
Is there some workaround for this problem?
Thanks a lot
Upvotes: 4
Views: 2731
Reputation: 2080
Declare the case class 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) {
}
This is according to Iulian Dragos commenting on SI-844
Upvotes: 3
Reputation: 63359
One possibility would be to hide (a bit) the class from your users:
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
)
}
This way there is no conflict and you still can pattern match on DeptEntry.Value
if you need. It depends on your use case if this solution is convenient or not. If you want that the trait has the proper val
s, you can declare it as
sealed trait DeptEntry {
val url: String
val fullName: String
val address: String
val city: String
}
and the fields in the case class
will override them.
Upvotes: 0
Reputation: 59994
When you create a case class
, the Scala compiler automatically generates a companion object with an apply method for you. This apply method has the same parameters as the case class's constructor. This is why you get this compiler error. The fact that you can't overwrite it ensures that stuff like that holds:
val inputUrl = "MyUrl://blabla"
val DeptEntry(outputUrl, _, _, _) = DeptEntry(inputUrl, "", "", "")
outputUrl == inputUrl
Try removing the case
from the class definition and write the companion object's apply
(and unapply
if you need extraction) yourself (and toString
, equals
and hashCode
in the class itself if needed).
Upvotes: 1
Reputation: 1224
You could make DeptEntry a "normal" (not case class) class. Or you can use a Method with a different name in the Object. (e.g. DeptEntry.lowerCase(...))
Upvotes: 0