Tomer
Tomer

Reputation: 2448

Use a trait as a parameter of a case class

I have the following code:

trait Vehicle{
   val speed:Int
}

case class Car(speed: Int, color: String) extends Vehicle
case class Plane(speed: Int, numberOfEngines: Int) extends Vehicle

case class Storage(vehicle: Vehicle, size:Int)

When using a trait as one of the named parameters of a case class, I loose the benefits of a case class, for example the copy method.

So if I want to update a vehicle speed like this:

val x = Storage(Car(100, "red"), 10)
x.copy(vehicle = x.vehicle.copy(speed = 30)) //this will not work.

This is obvious. The thing is it looks like the design here is bad, and that's why I ended with this problem.

Is there a better way to model this?

Upvotes: 1

Views: 285

Answers (1)

Chetan Kumar Meena
Chetan Kumar Meena

Reputation: 354

The copy() method is defined for a case class and not for a trait. Since a trait can also be implemented by a plain class, there is no guaranty that all implementation of trait Vehicle will have a copy method.

You now have two options

  • add a method withUpdatedSpeed(speed): Vehicle to Vehicle trait, so each subClass will provide a implementation

  • or case match on x.vehicle and manually construct vehicle Instances.

Upvotes: 1

Related Questions