views:

165

answers:

10

Hi!

Does anyone here have opinions about when to user inheritance and when to use an identifier instead?

Inheritance example:

class Animal 
{
    public int Name { get; set; }
}

class Dog : Animal {}

class Cat : Animal {}

Identifier example:

class Animal 
{
    public int Name { get; set; }

    public AnimalType { get; set; }
}

In what situations should i prefer which solution and what are the pros and cons for them?

/Lina

+2  A: 

I would use inheritance, if the inheriting classes (Cat and Dog in your example) have a different interface (methods or fields), or if they are used to select different behaviour. For instance in an actual project I have a base-class for generating HTML-code. Depending on the situation I create the correct subclass, that generates the right HTML. This classes have (mostly) the same interface, but their behaviour is so different, that I don't want to select it via if or switch.

Mnementh
+6  A: 

It depends on the type of the actions you need to be done in your system. For example if you have some common action that should be done in the different way for each of your objects than you should use inheritance, e.g.:

class Shape 
{
    public abstract void Draw();
}

class Circle : Shape 
{
    public override void Draw()
    { 
        /* Custom implementation for Circle. */
    }
}

class Box : Shape 
{
    public override void Draw()
    { 
        /* Custom implementation for Box. */
    }
}

On the other hand if some type of and object more looks like its property you should use what you called as "identifier":

enum Color
{
    Red,
    Green,
    Blue
}

class Box
{
    public Color BoxColor { get; set; }
}

You can use inheritance here (but it doesn't look so good): RedBox, BlueBox, etc. The difference is that all boxes (even ones with different color) would be handled in the same way and their behavior will be common.

Andrew Bezzub
+1  A: 

Have a look at where you use the code and how you use it. I find that the inheritance always lends itself when you have distinct objects that have a good opportunity for polymorphism.

Think a logging solution, the way to log log(string info) should be inherited to an object that is distinct in what its doing, such as logging to disk, log to network, screen etc.)

I've found a code smell is upcasting, when you have to go back to the real class to do something. If you are doing that then you probably haven't used it appropriately.

Inheritance is just a tool, don't use it because you can, use it because it will help you write clearer code that runs more efficiently.

Spence
+1  A: 

Inheritance is, to my mind, preferrable when behaviour must change according to the given identifier. As an example, if tyou simply want to provide your Animal a walk() method, you don't have to provide subclasses (as dogs and cats seems, from far away, to walk the same way).

However, if you want them to have some makeNoise(Mood mood) method, inheritance will be useful :

class Cat {
    public void makeNoise(Mood mood) {
        swithch(mood) {
            case happy:
                purr();
                break;
                // and so on
Riduidel
+3  A: 

What you call an "identifier" I would call an enum approach.

Using an enum to sub-divide is only suitable to distinguish a small, fixed set of possibilities. When you over-extend it you will see switch statements appearing everywhere in your code and that is a strong indicator you should use inheritance instead.

Henk Holterman
A: 

Thats faily simple, the two come to solve two diffrent issues, When you have diffrent behaviors, you should use Inheritance, for example, if the animal class has a behavior of "speak" it should be implemented using polimorphism and inheritance.

MindFold
+3  A: 
  • If the only difference between animals is their type, use the AnimalType property.

  • If different animals have different implementations of properties and methods or additional ones, create classes that derive from Animal.

    If checking for the type of animal is a common use case, consider providing a AnimalType property as well, as an alternative to lots of is/as.

dtb
+1  A: 

When going from general to specialized I would say go with inheritance. That way (in relation to your example) you would only have to make the walk, eat, sleep, etc. methods once. If they are on the same level however it would be better to simply use identifier. For example. You would not want to base a cat off of a dog, because then you would have to disable options in addition to adding new ones.

Adkins
+1  A: 

Inheritance will tightly couple the behaviour of the Cat and Dog to that of an Animal. Which may be what you want.

However, if you are trying to create a universe where anything is possible, and an animal can change its type, you may prefer to use the identifier approach..

But you can take this further.

According to the Gang of Fours design patterns you should

"Favor 'object composition' over 'class inheritance'."

An animal is only a dog because it has a tail that wags and it barks. In your universe where over time a dog might learn to talk, you will want to be able to modify this behaviour.

You could then try abstracting out its behaviour, and then within this behaviour you could use inheritance.

With this class structure :

class Tail
{
  DoYourThing()
}

class WaggyTail : Tail
{
  DoYourThing()
  {
    // Wag
  }
}

class Noise
{
  DoYourThing()
}

class Bark : Noise
{
  DoYourThing()
  {
    // Bark
  }
}

class Talk : Noise
{
  DoYourThing()
  {
     // Talk
  }
}

class Animal
{
   public Noise { get; set; }
   public Tail { get; set; }
}

You can set up your cats and dogs :

  Animal dog = new Animal { Noise = new Bark(), tail = new DoggyTail() }
  Animal cat = new Animal{ Noise = new Purr(), tail = new CattyTail() }

.. then when you need your super breed you can simple change their behaviour

dog.Noise = new Talk();

.. Hey presto, your dog can now talk.. If you need your dog to then Sing, you just create a new Sing class.. no further changes needed.

Mongus Pong
A: 

Ok, my new rule of thumb will be to go for inheritance if the classes have diffrent behaviors, otherwise I will go for an identifier of some sort. (Of course the final decision will depend on the environment in which the classes shall be used). Thank you for all of your answers!

Lina