Reputation: 8681
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
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