0fnt
0fnt

Reputation: 8681

Scala OO- optionally extend a trait

Not sure if such a thing is even possible, but the effect I'm looking to achieve is the following: I have a trait called physically situated which requires an int (corresponding to a person's city) to be present as a variable on the subclass.

class Building extends PhysicallySituated //A building has an address
class OilTanker extends Ship //An oiltanker is always moving around
class Yacht extends Ship with Option[ PhysicallySituated ] //a Yacht could have an address

How should I model such a scenario, given that PhysicallySituated has methods for operation on locations? What I'm looking for is that calling a method on ship returns an optional value of the type that the original method in PhysicallySituated would return. I'm aware that I could use an instance of PhysicallySituated and call this instance's methods, but then that goes against the best practices of encapsulation.

I should note that my understanding of Scala is medium-level, but I'm open to reading up any advanced concepts if they are pointed out

Upvotes: 2

Views: 72

Answers (1)

yǝsʞǝla
yǝsʞǝla

Reputation: 16422

Would that work for you? (Ran with Scala REPL):

trait Address

case object EmptyAddress extends Address

case class NonEmptyAddress(addrStr: String) extends Address

trait Situated {
  val address: Address
}

trait OptionallySituated extends Situated {
  val address = EmptyAddress
}

trait PhysicallySituated extends Situated {
  val address: NonEmptyAddress
}

class Building extends PhysicallySituated {
  val address = NonEmptyAddress("this is my place")
}

class Ship

class OilTanker extends Ship

class Yacht extends Ship with OptionallySituated

scala> val stuff = List(new Building, new Yacht)
stuff: List[Situated{val address: Product with Serializable with Address}] = List(Building@7e1f584d, Yacht@7dff6d05)

scala> stuff.map(_.address)
res0: List[Product with Serializable with Address] = List(NonEmptyAddress(this is my place), EmptyAddress)                        

You can use Option[Address] with Some and None instead of defining address classes above as well.

Upvotes: 3

Related Questions