Lesson 08.2 – Using class constructors with derived classes

Lesson Objectives

At the end of this lesson, you will know…

  • How a child (derived) class calls the constructor of its base class

 

Let’s clean up the code a little

Adding a constructor to a base class is a little more involved than adding one to a class that doesn’t have any derived (child) classes.

When you create an object from a derived class, it uses the constructor for both that class and its base class. So, if you add a custom constructor to your base class, you need to have a way for the derived class to pass values to it.

If you think about this, it makes sense why this needs to be done. With a custom constructor, you are saying, “I need these values before I can create this object.” When you create an object from a derived class, the base class still needs to have those values. So, you have to pass them to the derived class’ constructor, which passes them on to the base class’ constructor.

Here’s how you 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 Item class, in the Engine project, to start editing it. After the properties, add these lines, to make your constructor:

NOTE: If you try to build the solution right now, you’ll see there are errors with the HealingPotion and Weapon classes. These are the classes that are derived from the Item class, and [right now] they don’t have any values to pass to the Item class’ new constructor.

Step 3: Open the HealingPotion class, and add these lines to make its new constructor:

Notice that the HealingPotion constructor has parameters for the one property it has (AmountToHeal) and the three properties it uses from the base class (ID, Name, and NamePlural).

Inside the constructor, it sets the AmountToHeal property to the value that was passed through the amountToHeal parameter.

Also notice that after the constructor has a list of its parameters, it has this piece of code:

What that does is take the values from the parameters in the HealingPotion constructor (id, name, and namePlural) and passes them on to the constructor of the Item class. This is how we get parameters into the base class, when instantiating a derived class.

Step 4: Edit the Weapon class, by adding this constructor code:

After you add this, you can try rebuilding the solution. Now, since the derived classes are passing the required values to the base class, it will build without any errors.

Step 5: Edit the LivingCreature class. Add this constructor code:

Again, if you try to build the solution now, you’ll get an error that the Monster and Player classes (the classes that derive from LivingCreature) have a problem.

Step 6: Edit the Monster class, by inserting this constructor:

Step 7: Insert this constructor code into the Player class:

Now, if we try building the solution, we get an error. That’s because in the SuperAdventure UI code, we are instantiating a Player object without any parameters. Now that we have a custom constructor in the Player class, we need to use that and pass in the appropriate parameters.

Step 8: Right-click on SuperAdventure.cs, in the SuperAdventure project, then select “View Code”. Change line 23 to this:

Now that we are passing all the values in the constructor, to set the player object’s properties, we can delete lines 25 through 29, where we were setting the properties individually.

You could leave lines 25 through 29. They’ll still work, and they won’t hurt anything. But you’re already setting the properties to those values, so you might as well remove them and make your code a little cleaner.

 

Summary

You’ll probably need to use some amount of inheritance in any decent-sized program. And now you know how to make a custom constructor work in classes that use inheritance.

This may be overkill for the simple game that we’re building. However, you’re going to need to know how inheritance works if you program in C#, or another object-oriented programming language. Hopefully, with small, simple classes like these, it’s easy to understand.

 

Source code for this lesson

Get it from GtiHub: https://gist.github.com/ScottLilly/b460c4adbe1abde3c7f4

or DropBox: Lesson 08.2 – https://www.dropbox.com/sh/3eyuvmlc1j3dwy8/AAArG5VanmweSV5Yt1If8iTea?dl=0

 

Next Lesson: Lesson 09.1 – Using your classes as datatypes

Previous lesson: Lesson 08.1 – Setting properties with a class constructor

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

23 thoughts on “Lesson 08.2 – Using class constructors with derived classes

  1. Why you didnt pass currentHitPoints and maximumHitPoints vars to Monster’s base class from Monster’s consructor?

    1. In Step 6, at the end of the parameter list, the code “: base(currentHitPoints, maximumHitPoints)” passes the values for currentHitPoint and maximumHitPoint (from the Monster parameters) to the base class constructor parameters.

      1. It’s missing from the walkthrough though. This step stumped me as well until I checked your source files. In the walkthrough you have

        public Monster(int id, string name, int maximumDamage, int rewardExperiencePoints, int rewardGold, int currentHitPoints, int maximumHitPoints)

        But in the source files you have

        public Monster(int id, string name, int maximumDamage, int rewardExperiencePoints, int rewardGold, int currentHitPoints, int maximumHitPoints) : base(currentHitPoints, maximumHitPoints)

  2. Note: First line in Monster is
    public Monster(int id, string name, int maximumDamage, int rewardXP, int rewardGold, int currentHitPoints, int maximumHitPoints):base(currentHitPoints, maximumHitPoints)

  3. Ah, it is there. I was also a little stumped at first.

    It was not obvious initially, but in the example code for Step 6 there is a scroll bar that you can use to scroll to the right to see the rest of the code.

  4. “I’m getting an ‘object’ does not contain a constructor that takes 2 arguments” on line 20 of Monster.cs?

    1. Hi Brodie,

      I’m sorry I wasn’t able to answer earlier. I didn’t have Internet in my new apartment until last night.

      The plug-in that shows the code samples on the site works a little strangely, so you might not be able to see all the changes that needed to be made. I think the problem may be in the Monster class. Check it against the code on GitHub here https://gist.github.com/ScottLilly/b460c4adbe1abde3c7f4. If that doesn’t fix the problem, plese let me know. I should have some time to look into it a bit more this weekend.

  5. When inserting the constructor into Monster.cs, I get this error: “CS0029 Cannot implicitly convert ‘string’ to ‘int’ on line 20” (line 20 is “Name = name”). Help?

    1. Hi Leo,

      Can you double-check these three things?

      1. Make sure that you have the LivingCreature class as a base class for Monster:

      Line 9 (Monster.cs): public class Monster : LivingCreature

      2. That you have the Monster constructor calling the base constructor correctly (especially with the parameters in the correct order):

      Line 17 (Monster.cs): public Monster(int id, string name, int maximumDamage, int rewardExperiencePoints, int rewardGold, int currentHitPoints, int maximumHitPoints) : base(currentHitPoints, maximumHitPoints)

      3. That the parameters are in the correct order, and have the correct datatypes, in the LivingCreature class:

      Line 14 (LivingCreature.cs): public LivingCreature(int currentHitPoints, int maximumHitPoints)

      Let me know if those are all correct and I can help you investigate further.

    1. You only include the datatype (“Player”) when you declare the variable – basically telling the compiler “We’re going to have a variable named ‘_player’. It’s going to hold a Player object. So set aside some space for it”.

      We’ve already done the declaration higher up with the line “private Player _player;” When we declared the _player variable, it was at the class level (inside the curly braces for the class, but outside all the methods of the class). So, _player is visible anywhere inside the class. When we do “_player = new Player();”, we’re only filling the already-declared variable with the object.

      If you want to, you could add in “Player” to that line. You should see an error that says the _player variable has already been declared.

  6. Why don’t you just make constructors in classes for everything? For example:

    public class Location1 : Location

    {

    public Location1()

    {

    id = 1; name = “Home”; description = “This is your home”;

    }

    }

    1. Hello Sanek,

      In your sample, Location1 would be a child class of Location. We normally only create child classes when we want to add more details for a smaller set of the base class. For example, if we wanted a MountainLocation class that would also include a Height property. For the Location class, we don’t need that, because we are only going to create multiple Location objects.

      This might be clearer after lessons 09.1, 10.1, and 11.1. Those are where we start to populate our “World” with the different locations. If those lessons do not make it clear, please let me know.

  7. Hi there,

    First of all I want to say that this series has been a big help for me and I realize that this article is old and is designed for beginners, but one thing has me stumped. Is it an acceptable coding standard to create class constructors that are so large?

    The monster class’s constructor is huge and has well over 5 parameters. I could’ve sworn that I read somewhere that a class constructor should usually contain no more than 4 parameters at the most, otherwise it’s likely you can extract a further class out of it. Is this an incorrect statement or have you simply made these constructors to ease the simplicity of the lessons

    I’m still fairly new to programming in general and creating a clean, refactored, project standard style of source code is something I find myself worrying about constantly so please excuse me if my comment is confusing or incorrect I’m just merely confused and curios as to what a good coding practice would be when it comes to constructors.

    1. Hi James,

      You are correct. It’s generally best if your constructor has fewer parameters. Actually, you could say that is true for all functions. However, for the Monster class, I don’t see a great way to group any of the parameters into a their own class. We could potentially group rewardExperiencePoints + rewardGold into a Reward class, and currentHitPoints + maximumHitPoints into a HitPoints class. But that would only eliminate one parameter per object, and require us to add a little complexity by needing to instantiate, and populate, the two new classes, to pass into the Monster class constructor.

      This would definitely make sense if we were writing a Customer class, and wanted to capture their personal information, including a billing address and shipping address. Instead of passing in individual parameters for BillingStreetAddress, BillingCity, BillingStateProvince, BillingPostalCode, ShippingStreetAddress, ShippingCity, ShippingStateProvince, ShippingPostalCode, etc., it would make sense to create an Address class. Then, we would instantiate an Address object for the billing address, another one for the shipping address, and pass those objects in the Customer class constructor.

      This is one of those situations where you need to look at your options and decide which seems best to you.

  8. Hello Scott,

    This is a great lesson in a great series! One question related to this lesson though.

    I am creating a game where things like Creature, Player, Location etc. are abstract classes, and then specific creatures like Pig, or specific Player Professions and Location Types etc. are child classes of that abstract class.

    I believe that in one of the earlier lessons you mentioned (which I also remember from some other course) that you cannot create an instance of something that belongs to an abstract class. Thus I set up everything so that only derived classes have constructors. In fact, when I try to create a constructor for an abstract class, I receive an error in the editor.

    Am I right in saying that abstract classes cannot have constructors on their own (which would be logical, since they cannot be instantiated), or is that incorrect?

    Thanks in advance for your reply and have a great day!

    Mike

  9. Just wanted to say it is such a good tutorial to get started with c#. Thank you for putting so much effort in it with a step by step guide! It isn’t to complex so far, which i really like.
    I hope I finish the whole tutorial.
    Regards from Berlin_GER

  10. Hi, when i open visual studio 2015 and open project nothing is opening! Can you help? I can click start button and it opens my game but none of the code is opening. Thanks, Danny

    1. If you want to view or edit one of your class files, you can double-click on the file in the Solution Explorer part of Visual Studio (the upper-right section, where all the projects and classes are).

      Please tell me if that doesn’t solve the problem.

Leave a Reply

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