Just like humans, code code classes & structs can inherit from others. Like we as humans inherit characteristics and traits from our parents , so can classes.
We can inherit our eye colour, skin colour, hair colour, genetic intolerances and allergies.
This can work the same way in coding. We can give a class or struct a parent class to inherit from.
How does inheritance work
Well, unlike our human parents where only certain items are inherited, in code we inherit all the parent's traits and characteristics from properties , methods and modifiers.
Lets take an easy real life example of lets say a Bank. It should be pointed out although this is an example, it would not be an ideal real life usage, it is merely just as an example of inheritance.
public class Bank
{
public int Id { get; set; }
public string Name { get; set; }
public string SortCode { get; set; }
public void PaySomone(string accountNumber, string sortCode)
{
//some logic to pay the account number and sort code
Console.WriteLine($"Paid {accountNumber} and {sortCode}");
}
}
Ok so we have our bank, but there can multiple types of bank, for example an Online only bank, or a physical bank, lets scope these out.
Now normally we'd write it like this:
public class OnlineBank
{
public int Id { get; set; }
public string Name { get; set; }
public string SortCode { get; set; }
public string BankHomePage { get; set; }
public void PaySomeone(string accountNumber, string sortCode)
{
//some logic to pay the account number and sort code
Console.WriteLine($"Paid {accountNumber} and {sortCode}");
}
}
which is a bad way of doing it, as you'll see next when we create the PhysicalBank class.
public class PhysicalBank
{
public int Id { get; set; }
public string Name { get; set; }
public string SortCode { get; set; }
public string BankAddress { get; set; }
public void PaySomone(string accountNumber, string sortCode)
{
//some logic to pay the account number and sort code
Console.WriteLine($"Paid {accountNumber} and {sortCode}");
}
}
Can you see why this would make the code smell a bit? It doesn't follow the D.R.Y principle (Don't Repeat Yourself). There's identical code in both classes, and there is no need to they share multiple properties, methods and logic.
We can fix this using inheritance.
Inheritance Fix
Lets restructure the OnlineBank and PhysicalBank to utilise an inherited class that contains common logic.
First, we create a base class like so:
public class Bank
{
public int Id { get; set; }
public string Name { get; set; }
public string SortCode { get; set; }
public void PaySomeone(string accountNumber, string sortCode)
{
//some logic to pay the account number and sort code
Console.WriteLine($"Paid {accountNumber} and {sortCode}");
}
}
So here we have some properties and a method that all banks will have.
Now we can inherit from this for our OnlineBank class using the "{classname} : {classname}" syntax; By using the : character we tell the code this class will inherit from this class.
We can now apply this to our OnlineBank class, and add some OnlineBank specific properties.
public class OnlineBank : Bank {
public string BankHomePage {get;set;}
}
public class PhysicalBank : Bank {
public string BankAddress {get;set;}
}
So now the sub classes contain their own properties, which are specifically for Online and Physical banks, however, they also have access to their parents properties and methods too. We can test this by running the following code in a console application.
using System;
namespace Bank
{
internal class Program
{
private static void Main(string[] args)
{
Console.WriteLine("Beginning Bank Transaction...");
var onlineBank = new OnlineBank();
onlineBank.PaySomeone("012345898", "01-01-01");
var physicalBank = new PhysicalBank();
onlineBank.PaySomeone("987654321", "10-10-10");
Console.ReadLine();
}
}
public class Bank
{
public int Id { get; set; }
public string Name { get; set; }
public string SortCode { get; set; }
public void PaySomeone(string accountNumber, string sortCode)
{
//some logic to pay the account number and sort code
Console.WriteLine($"Paid {accountNumber} & {sortCode}");
}
}
public class OnlineBank : Bank
{
public string BankHomePage { get; set; }
}
public class PhysicalBank : Bank
{
public string BankAddress { get; set; }
}
}
Here you can see we're now able to access the PaySomeone() method from within both classes and re-use this functionality, without declaring it within each Bank sub class. That's the basics of inheritance.
Although , this basic form of inheritance is simple and helpful it's not flexible, or offering much in terms of re-usability and scalability, say we wanted to dictate many other functions which both can do but in different ways, for example pay in money, or cash a cheque. This is where interfaces, and abstract classes come into play.
In the next chapter of this series we'll begin to look at Interfaces and how they can be used in inheritance.