I'm exercising the decorator design pattern in Scala. I have the following implementation of a "Player".
// interface for the player
trait Player {
def jump(): Unit
def swim(): Unit
}
// a beginner player can't jump nor swim
class Beginner extends Player {
def jump(): Unit = throw Error()
def swim(): Unit = throw Error()
}
// movement decorator abstraction
abstract class MovementDecorator(my_player: Player) extends Player {
}
// concrete decorator
class Swim(player_x: Player) extends MovementDecorator(player_x) {
def jump(): Unit = throw new Error("I can't jump")
override def swim(): Unit = println("I swam!")
}
// concrete decorator
class Jump(player_x: Player) extends MovementDecorator(player_x) {
override def jump(): Unit = println("I jumped!")
def swim(): Unit = throw new Error("I can't swim")
}
A concrete Player (i.e. Beginner) can't have moves such as jump() or swim(). But I can decorate aka wrap the object with the Swim and/or Jump classes to give the Beginner that capability.
However, when I run the main method, I get the outputs shown with comments.
@main
def main(): Unit = {
val swimmer = Swim(Beginner())
swimmer.swim() // "I swam!"
val jumper = Jump(Beginner())
jumper.jump() // "I jumped!"
val swimmer_jumper = Jump(Swim(Beginner()))
swimmer_jumper.jump() // "I jumped!"
swimmer_jumper.swim() // Exception at Jump.swim: I can't swim
}
I want to keep the following to create my object
val swimmer_jumper = Jump(Swim(Beginner()))
Is there a specific way of overriding methods that I'm missing? I thought when you override a method it overrides any other method of the object -- and it becomes the preferred one.
Any help would be appreciated!
Aucun commentaire:
Enregistrer un commentaire