Inheritance

Today, we’ll start our journey of discovery into one of the four cornerstone principles of Object-Oriented Programming (OOP or just OO) – Inheritance. Previously, we have met Abstraction & Encapsulation, with Polymorphism yet to come.

Note: This article is purely concerned with traditional class-based Inheritance. There is another type of Inheritance, called Prototypal Inheritance, used in JavaScript, which we won’t get into today. We’ll leave that for another time.

What is Inheritance?

Inheritance allows us to share behaviour between classes – it’s a means for enabling code reuse. The class containing shared behaviour is the parent class. Other names are super or base class. Conversely, classes using the shared functionality of parent classes are children. Other monikers for child class are derived class or subclass.

Inheritance is a powerful technique for building up significant behaviour in a hierarchy of classes. 

It’s a one-way relationship. A subclass is dependent on the superclass. However, a superclass is not dependent on the subclass.

Let’s look at a trivial example where we use Inheritance: 

  public class Dog
  {
     public void Bark()
     {
        Console.WriteLine("Woof! Woof!");
     }
  }

What happens when we call Bark() on an instance of Dog?

  var dog = new Dog();
  dog.Bark();

The output is “Woof! Woof!” 

Now, class Chihuahua derives from Dog:

  public class Chihuahua : Dog
  {
  }

We did not define Bark() on class Chihuahua. Yet we don’t get a compilation error when trying to call Bark() on an instance of Chihuahua:

  var chihuahua = new Chihuahua();
  chihuahua.Bark();

And the output when running this code?

“Woof! Woof!” 

Class Chihuahua is a child to class Dog and has access to Dog.Bark().

Subclasses inherit the implementations from their parents. Nice! 

That’s great. However, what if we wanted Chihuahua to bark differently?

Yes, that’s possible.

Firstly, we change method Bark() to be virtual on Dog. 

  public class Dog
  {
     public virtual void Bark()
     {
        Console.WriteLine("Woof! Woof!");
     }
  }

We’re signalling to the compiler that subclasses of Dog may have different implementations for Bark(). 

We must also implement a new version of Bark() in Chihuahua:

  public class Chihuahua : Dog
  {
     public override void Bark()
     {
        Console.WriteLine("Yap! Yap!");
     }
  }

What will the output be?

  var chihuahua = new Chihuahua();
  chihuahua .Bark();

Produces “Yap! Yap!” 

Class Dog is unaffected by what happens to subclass Chihuahua. As before

  var dog= new Dog();
  dog.Bark();

Produces “Woof! Woof!”

There is too much to Inheritance for a single article. It’s one of the first code reuse patterns that junior developer tend to come across. Now, developers like reuse, so this is good. However, it can lead to Inheritance being overused and become problematic later on. 

That’s it for today. There is a lot more to cover off regarding Inheritance:

  • What kind of parent class methods are visible to child classes?
  • What are abstract methods?
  • What are abstract classes?
  • Why is Inheritance considered bad? (Spoiler: It’s not bad – it’s just a tool, and if used in the wrong context, it can cause problems.)
0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply