# Object Oriented Design

Suppose you have the following:

``````     +--------+     +------+
| Animal |     | Food |
+-+------+     +----+-+
^                 ^
|                 |
|                 |
+------+              +-------+
| Deer |              | Grass |
+------+              +-------+
``````

`Deer` inherits from `Animal`, and `Grass` inherits from `Food`.

So far so good. `Animal` objects can eat `Food` objects.

Now lets mix it up a bit. Lets add a `Lion` which inherits from `Animal`.

``````     +--------+     +------+
| Animal |     | Food |
+-+-----++     +----+-+
^     ^           ^
|     |           |
|     |           |
+------+ +------+     +-------+
| Deer | | Lion |     | Grass |
+------+ +------+     +-------+
``````

Now we have have a problem because `Lion` can eat both `Deer` and `Grass`, but `Deer` is not `Food` it is `Animal`.

With out using multiple inheritance, and using object oriented design, how do you solve this problem?

FYI: I used http://www.asciiflow.com to create the ASCII diagrams.

• Modelling the real world is usually a problem sooner or later, because there is always something strange going on (like flying fish, a fish or a bird? but a penguin is a bird, cannot fly and eats fish). What @Ampt says sounds plausible, an Animal should have a collection of stuff it eats. Jul 19, 2013 at 20:09
• I think Animal should inherit from Food. If something tries to eat a Lion, just throw an InvalidOperationException. Jul 19, 2013 at 20:35
• @RalphChapin: All kinds of things eat lion (vultures, bugs, etc). I think animal and food are artificial distinctions that will break down because they're not broad enough (all animals are some other animals food, eventually). If you classed on "LivingThing" you'd only have to deal with the edge cases with plants that eat non-living things (minerals,etc), and it wouldn't break anything to have LivingThing.Eat(LivingThing). Jul 19, 2013 at 20:40
• Sharing your research helps everyone. Tell us what you've tried and why it didn’t meet your needs. This demonstrates that you’ve taken the time to try to help yourself, it saves us from reiterating obvious answers, and most of all it helps you get a more specific and relevant answer. Also see How to Ask
– gnat
Jul 19, 2013 at 20:59
• This question has been answered by the game Age of Empire III. ageofempires.wikia.com/wiki/List_of_Animals Deer and Gazelle implement `IHuntable`, Sheep and Cow are `IHerdable` (controllable by human), and Lion only implements IAnimal, which does not imply any of those interfaces. AOE3 supports querying the set of interfaces supported by a particular object (similar to `instanceof`) which allows a program to query its capabilities. Jul 20, 2013 at 2:25

## IS A relationships = Inheritance

Lion is an animal

Car has a wheel

## CAN DO relationships = Interfaces

ICanEat

• +1 That is so simple and yet such a good summary of the 3 different relationship types Jul 20, 2013 at 11:25
• Alternative: `ICanBeEaten` or `IEdible` Jul 31, 2013 at 7:36
• CAN HAZ relationships = lolcats Jan 31, 2014 at 17:48
• How does this answer the question? Jun 29, 2015 at 8:30

OO is just a metaphor that patterns itself after the real world. But metaphors only go so far.

Normally there is no right way to model something in OO. There is a right way to do it for a particular problem in a particular domain and you shouldn't expect it to work well if you change your problem, even if the domain objects are the same.

I think this is a common misconceptions most Comp. Eng. students have in their first years. OO is not a universal solution, just a decent tool for some kind of problems that can model your domain reasonably well.

I didn't answer the question, precisely because we lack domain info. But with the above in mind you might be able to design something that suits your needs.

• +1 OO is a tool, not a religion. Jul 19, 2013 at 21:00
• I agree, there may not perfect solution if this problem continues to change and evolve. In it's current state does this problem lack domain info to come up with a solution? Jul 19, 2013 at 21:19
• Are you seriously thinking a real world is being modelled in OP? A relationship model is represented via an example. Jan 8, 2016 at 13:37
• @Basilevs That's kind of the implication, actually, since he mentions how animals behave in real life. One needs to be concerned with why does one need that behavior to be accounted for in the program, IMO. That said, it would have been nice of me to suggest some possible design.
– DPM
Jan 8, 2016 at 15:50

You want to further break down animals into their sub classes (or at least as far as makes sense for what you're doing). Given that you are working with what look like basic animals and two types of food (plants and meat), it makes sense to use carnivores and herbivores to further define an animal and keep them seperate. Here's what I drew up for you.

``````             +----------------+                   +--------------------+
|    Animal      |                   |      Food          |
|----------------|<--+Interfaces+--->|--------------------|
|                |                   |                    |
+----------------+                   +--------------------+
+           +                       +                 +
|           |    Abstract Classes   |                 |
|           |        |          |   |                 |
v           v        v          v   v                 v
+-----------------+  +----------------+     +------------+      +------------+
|   Herbivore     |  |  Carnivore     |     |   Plant    |      |   Meat     |
|-----------------|  |----------------|     |------------|      |------------|
|Eat(Plant p)     |  |Eat(Meat m)     |     |            |      |            |
|                 |  |                |     |            |      |            |
+-----------------+  +----------------+     +------------+      +------------+
+                    +                    +                   +
|                    |                    |                   |
v                    v                    v                   v
+-----------------+  +----------------+     +------------+      +------------+
|  Deer           |  |   Lion         |     |  Grass     |      |  DeerMeat  |
|-----------------|  |----------------|     |------------|      |------------|
|DeerMeat Die()      |void Kill(Deer) |     |            |      |            |
+-----------------+  +----------------+     +------------+      +------------+
^                    ^
|                    |
|                    |
Concrete Classes -------+
``````

As you can see, they both expose an eat method, but what they eat changes. The Lion can now kill a deer, the deer can die and return DeerMeat, and OPs original question of how to allow a lion to eat a deer but not grass is answered without engineering an entire ecosystem.

Of course, this gets interesting very quickly because a Deer could be considered a type of meat as well, but to keep things simple, I would create a method called kill() under deer, which returns a deer meat, and put that as a concrete class extending meat.

• Would Deer then expose an IMeat interface? Jul 19, 2013 at 20:21
• Meat isn't an interface, it's an abstract class. I added how I would implement that for you
– Ampt
Jul 19, 2013 at 20:24
• `Eat(Plant p)` and `Eat(Meat m)` both violate LSP. Jul 19, 2013 at 20:29
• How so @user61852 ? I purposely didn't expose Eat in the animal interface so that each type of animal could have it's own eat method.
– Ampt
Jul 19, 2013 at 20:36
• TCWL (Too complex, will leak). The problem is distributed and emergent and your solution is static, centralized and pre-defined. TCWL. Jul 31, 2013 at 13:40

My design would be like this:

1. Foods are declared as interfaces; there is an IFood interface and two derivated interfaces from it: IMeat and IVegetable
2. Animals implement IMeat and Vegetables implement IVegetable
3. Animals have two descendants, Carnivores and Hebivores
4. Carnivores have the Eat method that receives an instance of IMeat
5. Herbivores have the Eat method that receives an instance of IVegetable
6. Lion descends from Carnivore
7. Deer descends from Herbivore
8. Grass descends from Vegetable

Because Animals implement IMeat and Deer is an (Herbivore) Animal, Lion, which is a (Carnivore) Animal that can eat IMeat can also eat Deer.

Deer is a Herbivore, so it can eat Grass because it implements IVegetable.

Carnivores can´t eat IVegeable and Herbivores can´t eat IMeat.

• I'm seeing a lot of enumeration types here using inheritance just to constrain when the types being inherited implement nothing... Whenever you find yourself making types that don't implement any functionality at all, it's a giveaway something's a foot; you've expanded a model in the type system that yields no value to the usability in code Jul 19, 2013 at 21:34
• Remember than omnivores exist, like humans, apes and bears. Jul 19, 2013 at 23:46
• So how do you add that both, lions and deer, are mammals? :-) Jul 20, 2013 at 2:08
• @JimmyHoffa Those are called "marker interfaces" and are a totally valid use of interface. It needs to be code-reviewed to decide whether the use is justified, but there are many use cases (such as this one, where a Lion trying to eat Grass would throw a NoInterface exception). The marker interface (or the lack of) serves to foretell an exception that will be thrown if a method is called with unsupported arguments. Jul 20, 2013 at 2:30
• @rwong I understand the concept, never heard it formalized before; just my experience has been everytime a code base I've been working in has them it makes things more complex and harder to maintain. Perhaps my experience is however just been where people used them wrong. Jul 20, 2013 at 16:11

What foods an animal can eat don't actually form a hierarchy, in this case nature failed inexcusably to conform to simple object oriented modelling (note that even if it did, animal would have to inherit from food, since it is food).

Knowledge of what foods an animal can eat can't live entirely with either of the classes, so simply having a reference to some member of the food hierarchy can't be enough to tell you what things you can eat.

It's a many to many relationship. This means every time you add an animal, you need to figure out what it can eat, and every time you add a food, you need to figure out what can eat it. Whether there is further structure to exploit depends on what animals and foods you are modeling.

Multiple inheritance doesn't really solve this very well either. You need some kind of collection of things an animal can eat, or of animals that can eat a food.

• Like they say about regex "I had a problem so I used regex, now I have two problems", MI is along the lines of "I had a problem so I used MI, now I have 99 problems" If I were you I'd follow that vain you were poking at here though of the food knowing what can eat it, this actually simplifies the model a ton. Dependency inversion FTW. Jul 19, 2013 at 21:41

I will approach the problem from different side : OOP is about behavior. In your case, does `Grass` have some behavior to be child of `Food`? So in your case, there won't be `Grass` class, or at least, it won't be inherited from `Food`. Also, if you need to enforce who can eat what at compile time, it is questionable if you need `Animal` abstraction. Also, it is not rare to see carnivores eating grass, albeit not for sustenance.

So I would design this as (not going to bother with ASCI art):

`IEdible` with property `Type`, which is enum of meat, plant, carcass, etc.. (this won't change often and doesn't have any specific behavior, therefore there is no need to model this as class hiearchy).

`Animal` with methods `CanEat(IEdible food)` and `Eat(IEdible food)`, which are logical. Then, specific animals can check whenever then can eat given food in given circumstances and then eat that food to gain sustenance/do something else. Also, I would model classes Carnivore, Herbivore, Omnivore as Strategy pattern, than as part of animal hierarchy.

TL;DR: Design or model with a context.

I think your question is difficult because it lacks context of the actual problem you are trying to solve. You have some models and some relationships, but lack the framework in which it needs to work. Without context, modeling and metaphors don't work well leave the door open to multiple interpretations.

I think it more productive to focus on how the data will be consumed. Once you have the pattern of data usage it's easier to work backwards to what the models and relationships should be.

For example more detailed requirements will necessitate different object relationships:

• support `Animals` `eat`ing non-`Food` like `Gastroliths`
• support `Chocolate` as `Poison` for `Dogs`, but not for `Humans`

If we start in on the exercise of how to model the simple relationship presented the Food Interface may be best; and if that is the sum total how the relationships in the system then your fine. However, just a few additional requirements or relationships can vastly affect the models and relationships that worked in the simpler case.

• I agree but its just an small example an were not trying to model the world. For example you can have a Shark that eats Tires and License Plates. You can just make a parent abstract class with a method that eats any kind of object and Food could extend this abstact class. Jul 30, 2013 at 22:49
• @hagensoft: Agreed. I do get carried away sometimes because I constantly see developers modeling based on a metaphor they immediately seized upon, rather than looking at the how the data needs to be consumed and used. They get married to an OO design based on an initial idea and then try and force the problem to fit their solution instead of of making their solution fit the problem. Jul 31, 2013 at 0:07

ECS composition-over-inheritance approach:

``````An entity is a collection of components.
Systems process entities through their components.

Lion has claws and fangs as weapons.
Lion has meat as food.
Lion has a hunger for meat.
Lion has an affinity towards other lions.

Deer has antlers and hooves as weapons.
Deer has meat as food.
Deer has a hunger for plants.

Grass has plant as food.
``````

Pseudocode:

``````lion = new Entity("Lion")
lion.put(new Claws)
lion.put(new Fangs)
lion.put(new Meat)
lion.put(new MeatHunger)
lion.put(new Affinity("Lion"))

deer = new Entity("Deer")
deer.put(new Antlers)
deer.put(new Hooves)
deer.put(new PlantHunger)

grass = new Entity("Grass")
grass.put(new Plant)
``````

`Nature` is a `system` that loops through these entities, looking for what components they have through a generalized query function. `Nature` will cause entities with a hunger for meat to attack other entities that have meat as food using their weapons, unless they have an affinity towards that entity. If the attack succeeds, the entity will feed on its victim, at which point the victim will turn into a corpse deprived of meat. `Nature` will cause entities with a hunger for plants to feed on entities that have plant as food, provided that they exist.

``````Nature({lion, deer, grass})

Nature(entities)
{
for each entity in entities:
{
if entity.has("MeatHunger"):
attack_meat(entity, entities.with("Meat", exclude = entity))
if entity.has("PlantHunger"):
eat_plants(entity, entites.with("Plant", exclude = entity))
}
}
``````

Perhaps we want to extend `Grass` to have a need for sunlight and water, and we want to introduce sunlight and water into our world. Yet `Grass` cannot seek these out directly, as it does not have `mobility`. `Animals` may also need water, but can actively seek it out since they have `mobility`. It's pretty easy to keep extending and changing this model without cascading breakages of the entire design, as we just add new components and extend the behavior of our systems (or the number of systems).

With out using multiple inheritance, and using object oriented design, how do you solve this problem?

Like most things, it depends.

It depends on what you see 'this problem' to be.

• Is it a general implementation problem, e.g. how to 'get around' the absence of multiple inheritance in your chosen platform?
• Is it a design problem just for this specific case, e.g. how to model the fact that animals are also food?
• Is it a philosophical problem with the domain model, e.g. are 'food' and 'animal' valid, necessary, and sufficient classifications for the envisioned practical application?

If you're asking about the general implementation problem, the answer will depend on the capabilities of your environment. IFood and IAnimal interfaces could work, with an EdibleAnimal subclass implementing both interfaces. If your environment doesn't support interfaces, just make Animal inherit from Food.

If you're asking about these design concepts, the answer strongly depends upon what you intend to do with the model. If it's for a dog-eat-dog video game or even an application to track feeding schedules at a zoo, it might be enough to work. If it's for a conceptual model for animal behavioral patterns, it's probably a tad shallow.

Inheritance should be used for something that is always something else, and cannot change. Grass is not always food. For example, I do not eat grass.

Grass plays the role of a foodstuff for certain animals.

• Its just an abstraction. If that's a requirement then you could create more divisions that extend the Plant abstract class and make humans eat an abstract class like 'HumanEatablePlants' which would group the plants humans do eat into concrete classes. Jul 30, 2013 at 22:58

You have just come across the basic limitation of OO.

OO works well with hierarchical structures. But once you get away from strict hierarchies the abstraction does not work so well.

I know all about metamorphosis compositions etc. that are used to get around these limitations but they are clumsy, and, more importantly lead to obscure and hard to follow code.

Relational data bases were invented primarily to get away from the limitations of strict hierarchical structures.

To take your example grass could also be a building material, a raw material for paper, a clothing material, a weed or a crop.

A deer could be a pet, livestock, a zoo animal or a protected species.

A lion could also be a zoo animal or a protected species.

Life is not simple.

With out using multiple inheritance, and using object oriented design, how do you solve this problem?

What problem? What does this system do? Until you answer that, I have no idea what classes may be required. Are you trying to model an ecology, with carnivores and herbivores and plants, projecting species populations into the future? Are you trying to have the computer play 20 questions?

It's a waste of time to begin design before any use cases have been defined. I've seen this taken to ridiculous extremes when a team of about ten started producing an OO model of an Airline using software through pictures. They worked for two years modeling with no actual business problem in mind. Finally the customer got tired of waiting and asked the team to solve an actual problem. All that modeling was completely useless.