Sorry for this ugly question, but I didn't know how to word it. I'll give an example of what I mean:
A Human can be a Mage or a Warrior, so Mage and Warrior could inherit from Human. But what if Orc can be a both too? We can't say "a Human is a Warrior" or "a Warrior is a Human". Do Orc and Human (or a parent class, Humanoid) inherit all the skills, and then choose what to use?
I don't know if I should tag a specific language, since it's a general question about oop, but since different languages can have different approaches to the same problem, I would prefer answers from a C++ perspective.
Improve your modelling
When calculating the stats for your Mage, for instance, ask Race (not Human, or Orc) for things like int get_intelligence_bonus()
(abstract function in Race). If at all possible, interactions should be between Race and Class, not the concrete counterparts.
Use composition to actually construct your character:
Character::Character( std::unique_ptr<Race> r, std::unique_ptr<Class> c )
{
// calculate stats, etc...
}
You can use pure OOP for dynamic binding or if you prefer, you can use templates for static-time binding, but that's an orthogonal implementation issue. Either way, you need to get your class hierarchy right.
If you are new to C++ or if you only need race and class in the constructor, you may use const&
instead of std::unique_ptr<>
. But if you are serious about learning C++, do read about ownership semantics and variable lifetimes so you can better understand std::unique_ptr<>
.
http://en.cppreference.com/w/cpp/memory/unique_ptr
That's when I break out policy-based design. Then I can have Human<Warrior>
or Orc<Warrior>
or Orc<Mage>
. (Or turn it around if it makes more sense: Warrior<Human>
etc.) But that's if I know what's going on at compile time.
If I don't know until run time, I'd use a class Humanoid
which has a Race
(subclasses would be Orc
, Human
, etc.) and has a RPGClass
(subclasses Mage
, Warrior
, etc.)
In other languages, there are things such as protocols which can define the interface to an object, so that you don't have to define a base class full of abstract virtual methods and such. So RPGClass
and Race
would be protocols used to interface to classes such as Mage
and Human
respectively. Policies are just protocols resolved at compile time.
P.S. I have no idea how metaphorical (or not) your examples are...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With