Skip to main content
added 792 characters in body
Source Link
Flater
  • 59.5k
  • 8
  • 112
  • 171

Another possible reason to use inheritance is when some animal types require extra information that others don't. For example:

public Color FeatherColor { get; set; }

This obviously only belongs to a bird. If you use a single Animal class, then suddenly all animals could have a feather color, which is wrong.

And you don't want to be using null if you can avoid it. Long advice cut short: avoid null where possible.

Inheritance makes sure that only birds have feathers, but e.g. all animals have an age:

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

public class Dog : Animal { }

public class Cat : Animal { }

public class Bird: Animal
{
    public Color FeatherColor { get; set; }
}

Another possible reason to use inheritance is when some animal types require extra information that others don't. For example:

public Color FeatherColor { get; set; }

This obviously only belongs to a bird. If you use a single Animal class, then suddenly all animals could have a feather color, which is wrong.

And you don't want to be using null if you can avoid it. Long advice cut short: avoid null where possible.

Inheritance makes sure that only birds have feathers, but e.g. all animals have an age:

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

public class Dog : Animal { }

public class Cat : Animal { }

public class Bird: Animal
{
    public Color FeatherColor { get; set; }
}
Source Link
Flater
  • 59.5k
  • 8
  • 112
  • 171

You've shown us a limited part of the Animal class.

IF this is the only impact your animal type has, i.e. telling you which animal it is, it is better to favor the enum here as the derived classes aren't really being using to their full potential.

However, this is likely not the case. There might be some more animal logic. For example:

public class Animal
{
    public enum SpecificAnimal { Cat, Dog, Bird }

    public SpecificAnimal AnimalType { get; set; }

    public string SaySomething()
    {
        switch(this.AnimalType)
        {
            case SpecificAnimal.Dog:
                return "Woof";
            case SpecificAnimal.Cat:
                return "Meow";
            case SpecificAnimal.Bird:
                return "Tweet";
            default:
                return "...";
        }
    }
}

Here, it would be better to use inheritance, because each animal type has custom logic that is specific to its type.

public class Animal
{
    public virtual void SaySomething()
    {
        return "...";
    }
}

public class Dog : Animal
{
    public override void SaySomething()
    {
        return "Woof";
    }
}

public class Cat : Animal
{
    public override void SaySomething()
    {
        return "Meow";
    }
}

public class Bird: Animal
{
    public override void SaySomething()
    {
        return "Tweet";
    }
}

It may seem overkill for the example I used here, but in the real world your custom logic is going to be significantly more impactful than just returning a hardcoded string.

You don't want to have to stack all dog/cat/bird/... logic into a single class, because it gets way too cumbersome to juggle them all and not get distracted by them at the same time.