Shame that Swift is pretty much confined to iOS app development.
protocol Weapon {}
class Staff: Weapon {}
class Sword: Weapon {}
protocol Player {
associatedtype T: Weapon
var weapon: T { get set }
}
class Wizard: Player {
var weapon = Staff()
}
class Warrior: Player {
var weapon = Sword()
}
If you look through the later items in the series, it seems to get more complex than this. In particular, a character can use either 0 or 1 weapons at a particular moment, and either class can also use the Dagger weapon. It's not that each character inherently only has, and uses, the only weapon appropriate to that character -- this would make things quite a bit simpler.
Well, maybe someday Dotty will be a mainstream language...
trait Weapon
class Sword extends Weapon
class Staff extends Weapon
class Dagger extends Weapon
trait Player {
type T <: Weapon
}
class Wizard extends Player {
type T = Dagger | Staff
var weapon: T = null
}
class Warrior extends Player {
type T = Dagger | Sword
var weapon: T = new Sword
}
class Weapon: pass
class Sword(Weapon): pass
class Staff(Weapon): pass
class Dagger(Weapon): pass
class Player:
weapon: Weapon
class Wizard(Player):
weapon: Optional[Union[Dagger, Staff]] = None
class Warrior(Player):
weapon: Optional[Union[Dagger, Sword]] = Sword()
Until you want to model a bar-fight and then a chair (a piece of furniture) becomes a weapon, i.e. "class Chair: Furniture{}" turns into "Class Chair: Weapon {}". Or when the winter gets tougher and longer and "class Chair: Furniture{}" changes into "class Chair: Firewood{}". I know that there's probably a "solution" involving object "composition", but that would only mask the problem, will not really solve it.