Inheritance is an Object Oriented Programming concept (OOP) used to access and reuse the properties or methods of one class from another.
The class being inherited from is known as the ‘base’ class, where the one inheriting from the base class is known as the ‘derived’ class.
Let’s think of it like this:
John (derived class), is a Human, consequently he has Inherited certain abilities, he can Jump, Dance, SpinKick etc,
Zoltron however is an Alien, so he cannot Dance, but he has inherited the ability to Teleport. Both John and Zoltron are unique, yet they are both Sentient beings (base class), so they both share certain properties such as health and age.
Here is a simple diagram to illustrate.
Lets take a look at at writing this in Unity3d and CSharp with a slightly more practical game example.
When creating a class from within Unity, it will ‘extend’ MonoBehaviour as default (‘extend’ is another way to say ‘inherit from’ and will be used interchangeably in this post).
By extending the MonoBehaviour our classes get access to many useful functions like Update() and Start() and many more.
/* blank class created in unity */ /* BlankClass.cs */ using UnityEngine; using System.Collections; public class BlankClass : MonoBehaviour { void Start () { } void Update () { } }
So you have been inheriting all this time! How about that… But say we want more… Lets see how we can use inheritance in a more meaningful way to make our workflow more efficient.
Below we have an Enemy class which extends MonoBehaviour. Enemy will have the public functions Attack() and TakeDamage().
/*Enemy.cs*/ using UnityEngine; using System.Collections; public class Enemy : MonoBehaviour { public int health = 100; public void TakeDamage() { health -= 10; } public void DoAttack() { //Enemy does Spin Kick! WOAH //all enemies extending the Enemy class can access this attack } } }
Now we create a Goblin class which inherits from Enemy (Goblin is a type of enemy). By extending Enemy, Goblin now has access to the functionality of Enemy! (Enemy cannot however see the Attack() and TakeDamage() functions of Goblin).
Why this is important: As a project grows we may end up with 20 types of enemies. By extending the base class Enemy, we are able to reuse logic and have it neatly in one place, rather then having 20 different attack functions – remember D.R.Y !! As you can also see, because Enemy is extending MonoBehavior and Goblin is extending Enemy, Goblin gets full access to any MonoBehaviour functions such as Start(), Awake() and Update() etc.
/*Goblin.cs*/ using UnityEngine; public class Goblin : Enemy { void Start () { DoAttack(); } }
Overriding Inheritance
Quick Analogy: Timmy inherits a bicycle from his father, but Timmy says ‘screw you I have my own bike, it’s bigger and better!’
Lets now create another enemy type, this one will be Zombie. What if we don’t want to use the generic Attack() set in the Enemy class? Well, we can ‘override’ it. What this essentially means is that Zombie is aware that It can Attack() but wants to use its own Attack function with its own unique logic. To do this we need to to first mark the Attack function in the Enemy Class as ‘virtual’, this simply means that we are allowing the function to be overridden by inheriting classes.
/*Enemy.cs*/ using UnityEngine; using System.Collections; public class Enemy : MonoBehaviour { public int health = 100; public void TakeDamage() { health -= 10; } public virtual void DoAttack() { //This function is virtual, it can be overridden by inheriting classes } } }
Now in the Zombie class we create a new version of the DoAttack() function and mark it as ‘override’. The override tells the compiler that this function is overriding another
/*Zombie.cs*/ using UnityEngine; public class Zombie: Enemy { void Start () { DoAttack(); } public override void DoAttack() { //do Eat Brain attack } }
Limiting Access to Inheritance
Time for another analogy. Timmy Inherits his fathers fortune which includes the family house and business, the will however states that Timmy does not get the Ferrari. Timmy is sad. The ‘sealed’ keyword lets us prevent inheritance of a class or specific properties and functions.
public sealed void DoAttack() { //This function is sealed. It will not be accessible from inherited classes }
Chaining Inheritance
A derived class can only have one direct base class, however it can ‘chain inherit’ .
What this means is that you can have several objects sharing the inheritance of a base class, whilst inheriting from each other.
Inheritance is a relatively simple concept, which can often be challenging to explain in the context of programming, as each language as their own little nuances.
Hopefully this post has been helpful and not confused you further! I will make revisions and add to this post over the next few days, feel free to comment if i need to be clearer about anything.
[…] Understanding Class Inheritance In Unity3D […]
Previously I don’t use Class Inheritance, but now I understand the effective way how to create a Class. Thank you bro. 😀
Loving your blog. Great post but the section on limiting inheritance doesn’t really explain where to use the ‘sealed’ part. Ie On base or derived class?
I agree.
Thanks for the info! This is the first time I’ve learned about this whole topic, and it was very clear.
Thank you. I understand the first part since you nicely created the chart explaining what is base class and derived class. That Alien and Human example is awesome. But I honestly got lost in the below parts, especially since you did not explain every small details in those codes. For example, when do you have to use a full stop. When to use void, when to use monobehaviour, when to use ‘using’ etc. It’s just confusing to a beginner when it comes to those codes.