Lesson 07.1 – Inheritance and base classes

Lesson Objectives

At the end of this lesson, you will know…

  • Why you might use inheritance.
  • How to use inheritance and base classes

 

There is a lot of repetition in the class properties

Right now, we have seven classes in the Engine project: HealingPotion, Item, Location, Monster, Player, Quest, and Weapon.

You may have noticed that some of the classes have very similar properties. Some of the classes also represent the same type of thing. For instance:

  • HealingPotion, Item, and Weapon all have the properties ID, Name, and NamePlural. They all also represent items that a player may collect during a game.
  • Player and Monster share ID, CurrentHitPoints, and MximumHitPoints. They are both “living creatures” in the game.

When you have classes that represent the same type of thing, and have similar properties (or functions, as we’ll see later) that mean the same thing, you may want to use inheritance – another aspect of object-oriented programming.

We’re going to make the Item class the base class for HealingPotion and Weapon, since all of those classes have the properties that are in the Item class.

Then, we’re going to create a new LivingCreature base class, to hold the shared CurrentHitPoints and MaximumHitPoints properties of the Monster and Player classes.

Here is how we do that.

 


Link to video on YouTube

 

Step 1: Start Visual Studio Express 2013 for Desktop, and open the solution.

Step 2: Double-click on the HealingPotion class, in the Engine project. Change line 9 to this:

Adding the colon and Item class name after the HealingPotion class name is how we show that HealingPotion has a base class of Item. So, all the public properties and methods from the Item class now automatically show up in the HealingPotion class, even after we delete the lines for the ID, Name, and NamePlural properties.

HealingPotion is now a “child class”, or “derived class”, from the Item class. Those are the common terms you’ll hear other programmers use, for classes that inherit from another class.

Now, we can remove the ID, Name, and NamePlural properties from HealingPotion, since they are in the base class.

One of the most popular benefits of a base class is that you don’t need to duplicate properties and methods in all of its child classes. Child classes have access to variables/properties/methods/etc. that are in the base class – as long as their scope is not “private”. Anything that is private is only visible inside the base class.

So, the ID, Name, and NamePlural properties are now “in” the HealingPotion class, because they are in its base class, and not private.

Step 3: Do the same thing that you just did to the HealingPotion class to the Weapon class – add the Item base class and delete the lines with the three properties that are already in the Item class.

Step 4: We don’t already have a class with the properties we have in common with the Monster and Player classes, so create a new class, named LivingCreature, with the integer properties for CurrentHitPoints and MaximumHitPoints. Be sure to make this class public. A base class needs to be at least as visible (with regards to its scope) as its child classes.

Step 5: Change the Monster and Player classes so they have LivingCreature as a base class (add the colon and LivingCreature to the lines that start with “public class”), and remove the CurrentHitPoints and MaximumHitPoints properties from those two classes – since they’ll now use the properties from the base class.

Step 6: In the UI project, view the code of the SuperAdventure form (right-click on SuperAdventure.cs). Notice that there is no red line under the Player CurrentHitPoints and MaximumHitPoints properties on lines 25, 26, and 31 – even though you just deleted those properties from the Player class. That’s because the class inherited those properties from its base class – LivingCreature.

Step 7: Start the program, so you can see that the CurrentHitPoints value is still correctly displayed on the screen.

 

Summary

Now you know how, and why, you would create base classes for the classes in your program. This is especially helpful when you write larger applications, and you want to make sure that classes that are similar all act in a similar manner.

Base classes also let you share functions (Lesson 09), so you don’t have to duplicate the same code in several places – and worry about accidentally mistyping something in one of them.

There are some more advanced conditions to what is visible from the base class, in the “child” classes. But we won’t get into those in this guide.

 

Source code for this lesson

Get it from GitHub: https://gist.github.com/ScottLilly/e313a2f3c6401f784277

or DropBox: Lesson 07.1 – https://www.dropbox.com/sh/9nm2oczc0k513gl/AABi0rqkCPK31bVVoGEqBS-5a?dl=0

 

Next Lesson: Lesson 08.1 – Setting properties with a class constructor

Previous lesson: Lesson 06.1 – Creating the remaining classes

All lessons: Learn C# by Building a Simple RPG Index

 

14 thoughts on “Lesson 07.1 – Inheritance and base classes

  1. I just wanted to note:

    In step 4, you should be explicit about adding ‘public’ to ‘class LivingCreature’ …

    I got to step 6 and was still seeing red lines under the variables and realized it was because I did not declare the LivingCreature class as public.

    Anyway,

    Thanks!

  2. I think I might have missed a step? In the last lesson I don’t think you told us to add the properties to the class’s. Like ID ect. So that is a little confusing.

  3. I’m getting an error message saying “Inconsistent accessibility: base class ‘item’ is less accessible than class ‘HealingPotion’

    1. Make sure your Item class is defined as “public”, like this (on line 9, of Item.cs):

      public class Item

      By default, if you don’t add an “access modifier” (such as “public”, “private”, “internal”), a class is “internal”, which has less accessibility than “public”. And a base class cannot be less accessible than one of its child classes.

      If that doesn’t fix the problem, please let me know.

  4. What a nice, easy to understand introduction to inheritance. I am getting back into learning C# after a previous false start and so far your tutorials are great for reviewing the fundamentals.

  5. Step 2 is oddly worded: “Change line 9 by to this:”

    Also, in Step 2, you never explicitly tell us to delete the common “Item” properties out of “HealingPotion”. It’s easy to gather in the next few steps, but you may want to add something like that.

    I am TOTALLY enjoying this series and learning a ton. I hit a major brick wall in self-teaching with regard to Class-Object interaction in C# and this has helped tremendously. I cannot thank you enough!

  6. I know a lot of the basics of C# already from other tutorials and reading through Microsoft’s own articles, and in my pursuit of mastering C# I’ve come across forums where I’ve seen several people say it’s bad practice to make a lot of public variables, the question ofc being how do you then access variables in other classes, however do you agree that it is bad practice, I don’t really know what to believe. The public scope/protection level seems very useful and I currently don’t know of any other way to access variables in other classes.

    1. What I often do is have properties with public “get” and private “set”. With the public “get”, the property value can be viewed by the user interface (usually in a separate project from the “engine” classes). The property value would be modified by calling a public function on the class – which has access to the private “set”, because it is in the same class.

      For example, think of the CurrentHitPoints property in the Player class. The “get” would be public, to be displayed in the UI. To modify CurrentHitPoints, you would go through a public function in the Player class, such as:

      public void TakeDamage(int hitPointsOfDamage)

      TakeDamage can change the value of CurrentHitPoints, but could also have logic to make sure CurrentHitPoints is never negative (the lowest it would allow is zero). Because the “set” is private, everything that subtracts hit points would need to go through TakeDamage. So, we can be certain the value will never be below zero. If the “set” was public, the value could be changed anywhere in the program. Then, we would need to add zero-checking logic every place the code subtracted hit points.

      Let me know if that helps make it clearer.

Leave a Reply

Your email address will not be published. Required fields are marked *