Reputation: 5616
I have multiple classes deriving from one base class with a polymorphic method that accepts the enum type declared in the base class. I repeat the enum in the subclasses so that each subclass only accepts its own specific group of values:
class Character {
enum Actions {
}
func performAction(action: Actions) {
// Functions to be performed by all subclasses
}
}
class Warrior: Character {
enum Actions {
case Attack, Block, Charge
}
override func performAction(action: Actions) {
// Add subclass-specific behavior
}
}
class Wizard: Character {
enum Actions {
case Attack, CastSpell, Run
}
override func performAction(action: Actions) {
// Add subclass-specific behavior
}
}
This of course doesn't work and I get
'Actions' is ambiguous for type lookup in this context.
I can't delete the enum in the base class because then I get an undeclared type error for the method. I have a strong feeling I'm going about this all wrong and trying to reinvent the wheel. Can someone point me in the right direction? Thank you.
Upvotes: 0
Views: 480
Reputation: 32782
How about this approach:
enum Action {
case Attack, Block, Charge, CastSpell, Run
}
class Character {
final func performAction(action: Action) {
if self.allowedActions().contains(action) {
self.executeAction(action);
}
}
func allowedActions() -> [Action] {
// to be overriden in subclasses
return []
}
func executeAction(action: Action) {
// this will also be overriden in subclasses
}
}
class Warrior: Character {
override func allowedActions() -> [Action] {
return [.Attack, .Block, .Charge]
}
override func executeAction(action: Action) {
// do whatever is needed
}
}
class Wizard: Character {
override func allowedActions() -> [Action] {
return [.Attack, .CastSpell, .Run]
}
override func executeAction(action: Action) {
// do whatever is needed
}
}
You use one enum to hold all possible actions, and you define per subclass which actions are allowed.
This way you can treat all characters the same: ask for the actions they can perform, so you can show a menu for example, and then ask the character to perform that action.
We can go even further, by using structs instead of classes and associated values for enums, this being a more swift-ish approach, but also a little bit more complicated to setup (but more logical).
Upvotes: 1