0

I recently came across a problem related to class creation/modeling.

Model animal kingdom as classes. Use your classes to create various objects represented as a virtual zoo. Add 20 animals to this virtual zoo (in your main method of your program and make let each animal make a sound. This should not be 20 different species).

I thought about the problem and decided to go with an abstract class Animal rather than an interface. Then i added two classes Bird, Mammal as inherited them by Animal.

My implementation

  public abstract class Animal{

      abstract Sound MakeSound();
    }

    public class Bird : Animal
    {
       private Sound _sound;
       public Bird(Sound sound){
       _sound = sound;
    }
    public Sound MakeSound(){
          return _sound;
       }
    }
//same as above with Mammals

public class Program
{
  Animal crow = new Bird("Crow sound");
  Console.WriteLine(crow.MakeSound());

 Animal dog = new Mammal("Dog sound");
  Console.WriteLine(dog.MakeSound());

// and so on with other animals
}

My questions are -

  1. What is wrong with my implementation?
  2. What would be the correct way to design the animal kingdom as per oops concepts?
  3. In what scenario do we use an interface over abstract class and vice versa. (with real world example)

Kindly suggest some bang on online material where i can improve on such problems. Thanks.

  • Hey great question. I think you would get a better response and more help from a sister site of Stack Overflow called Code Review. https://codereview.stackexchange.com – rayepps Nov 25 '17 at 17:54
  • If you provide the sound through the constructor it makes no sense to create a whole hierarchy of classes. You could just have one class `Animal` and create all the animals from it: `var dog = new Animal("Dog sound");`. For the example to make sense, there should really be some code specific to a species in these classes. – Olivier Jacot-Descombes Nov 25 '17 at 18:13

2 Answers2

9

First of all, it's important to realize that though "model the animal kingdom in a class hierarchy" is a common beginner exercise, and often used in examples -- I use Animal, Mammal, Giraffe, Tiger, and so on all the time in examples -- it is not a realistic problem to solve using OO techniques. It's simply intended to get you thinking about the concepts in OO programming by thinking about a domain that you already understand well.

Real zoos which have software to manage their animal inventory do not build class hierarchies like this because their concerns do not actually include what mammals have in common over what birds have in common. Though animal kingdom analogies are useful to get going with OO, it's important to not come away with the belief that every feature that exists in a real-world hierarchy has to be modeled in the class hierarchy.

So, that said, the rest of my critique will be assuming that you really do want to model the animal kingdom as an exercise.

Second, the fundamental problem with your implementation is that the hierarchy is either not deep enough or too deep. The problem is that mammal and bird should be abstract because there is no thing in the world that is just a mammal or just a bird. What you want is an abstract class bird that extends animal, and then a concrete (and probably sealed!) class Crow that extends Bird.

Then the question to ask is: do I really need the mammal and bird levels at all? Are they useful to my program? Am I ever going to have a method that can take any mammal but no lizard? If its not useful then eliminate it, and go straight from animal to crow.

Third, the sound a crow makes is "caw caw", not "crow sound". :-)

Fourth, to answer your best question: you typically use an interface when you have several unrelated things that "can do" the same thing but with different implementations and you use an abstract class to share implementation details amongst classes that have an "is a kind of" relationship.

Making a sound is a something that a lot of things can do that are unrelated to each other. A bird and a piano are not the same kind of thing and they have different mechanisms, but they both make sounds. So making sound should be represented by an interface. A bird is a kind of animal, and there might be functions common to all animals that are specialized by birds.

In short: a bird is a kind of animal, so it should be a subclass. A bird can make a sound, and lots of other things can also, so making a sound should be an interface.

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
0

one of the reasons you want to use Interface is that C# does not support multiple inheritance.

In general, I would like to think of interface as ability or feature instead of being a model.

Something like:

    public interface ISwimable
    {
         int SwimmingSpeed { get; set; }
    }

    public interface IWalkable
    {
        int RunningSpeed { get; set; }
    }

Now if I have an animal that lives in water I would like it to implement ISwimable, and if I have an animal that can walk, its class should implement IWalkable, and if it can do both, it will implement both.

Yahya Hussein
  • 8,767
  • 15
  • 58
  • 114