Press "Enter" to skip to content

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:

public Item(int id, string name, string namePlural)
{
    ID = id;
    Name = name;
    NamePlural = namePlural;
}

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:

public HealingPotion(int id, string name, string namePlural, int amountToHeal)  :  base(id, name, namePlural)
{
    AmountToHeal = amountToHeal;
}

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:

:  base(id, name, namePlural)

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:

public Weapon(int id, string name, string namePlural, int minimumDamage, int maximumDamage)  :  base(id, name, namePlural)
{
    MinimumDamage = minimumDamage;
    MaximumDamage = maximumDamage;
}

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:

public LivingCreature(int currentHitPoints, int maximumHitPoints)
{
    CurrentHitPoints = currentHitPoints;
    MaximumHitPoints = maximumHitPoints;
}

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:

public Monster(int id, string name, int maximumDamage, int rewardExperiencePoints, int rewardGold, int currentHitPoints, int maximumHitPoints) :  base(currentHitPoints, maximumHitPoints)
{
    ID = id;
    Name = name;
    MaximumDamage = maximumDamage;
    RewardExperiencePoints = rewardExperiencePoints;
    RewardGold = rewardGold;
}

 

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

public Player(int currentHitPoints, int maximumHitPoints, int gold, int experiencePoints, int level)  :  base(currentHitPoints, maximumHitPoints)
{
    Gold = gold;
    ExperiencePoints = experiencePoints;
    Level = level;
}

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:

_player = new Player(10, 10, 20, 0, 1);

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

Source code on GitHub

Source code on DropBox

 

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

43 Comments

  1. Bulut Paradise
    Bulut Paradise October 12, 2014

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

    • Scott Lilly
      Scott Lilly October 16, 2014

      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.

      • Chad
        Chad December 30, 2014

        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)

        • Scott Lilly
          Scott Lilly January 1, 2015

          I believe that’s in Step 6 of the lesson here, unless there is a different problem that I’m not seeing.

  2. Sebastian
    Sebastian October 13, 2014

    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. Jake
    Jake March 20, 2015

    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.

    • Scott Lilly
      Scott Lilly March 20, 2015

      Yes, there’s a plug-in I use to format and display the source code. It’s the best one I’ve found, but it still has a couple bits of odd behavior. 🙁

  4. Brodie
    Brodie June 7, 2015

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

    • Scott Lilly
      Scott Lilly June 18, 2015

      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. Leo
    Leo June 22, 2015

    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?

    • Scott Lilly
      Scott Lilly June 23, 2015

      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.

  6. Tuguldur
    Tuguldur August 21, 2015

    why did you put _player =new Player(); instead of Player _player=new Player();

    • Scott Lilly
      Scott Lilly August 21, 2015

      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.

  7. Sanek
    Sanek January 5, 2016

    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”;

    }

    }

    • Scott Lilly
      Scott Lilly January 5, 2016

      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.

  8. James Johnson
    James Johnson April 1, 2016

    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.

    • Scott Lilly
      Scott Lilly April 1, 2016

      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.

  9. Mike
    Mike May 11, 2016

    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

  10. Malte
    Malte February 16, 2017

    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

  11. Danny
    Danny March 2, 2017

    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

    • Scott Lilly
      Scott Lilly March 2, 2017

      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.

  12. Jacob Cook
    Jacob Cook September 3, 2017

    public Monster(int id, string name, int maximumDamage, int rewardExperiencePoints, int rewardGold, int currentHitPoints,
    int maximumHitPoints) : base(currentHitPoints, maximumHitPoints)
    {
    ID = id;
    Name = name;
    MaximumDamage = maximumDamage;
    RewardExperiencePoints = rewardExperiencePoints;
    RewardGold = rewardGold;
    }

    Name = name; is coming up with error CS0029 (cannot implicitly convert type ‘string’ to ‘int’) i have followed the lessons and cannot figure it out, can anyone tell me what i’m doing wrong?

    • Scott Lilly
      Scott Lilly September 3, 2017

      Hi Jacob,

      The error message is saying that the existing code is trying to assign a string value to an integer property (or variable). That’s the “cannot implicitly convert type ‘string’ to ‘int'” part of the error message. It’s also telling you that this is happening with the “Name” property.

      So, check the datatype of the “Name” property. I’m guessing it is set to “int”, when it needs to be “string”.

      Please tell me if that is not the source of the error.

      • Jacob Cook
        Jacob Cook September 3, 2017

        That fixed it, thank you.
        Also thanks for creating this tutorial!

  13. BEM
    BEM September 23, 2017

    Scott Lilly thank you so much for creating this series. I’ve been doing code tutorials for a year and never could grasp a lot of the concepts. The way you relate this to a game makes it a lot easier to understand and not as boring. Appreciate it!

    • Scott Lilly
      Scott Lilly September 24, 2017

      You’re welcome. When I personally try to learn something, it always seems easier if there is a final project – and not just a lot of small, unconnected things.

  14. kashif
    kashif May 7, 2018

    ‘object’ does not contain a constructor that takes 2 arguments
    this appeared when i entered : base(currentHitPoints, maximumHitPoints)
    for monster.cs

    • Scott Lilly
      Scott Lilly May 7, 2018

      On line 9 of the Monster class, do you have this, so it knows to inherit from the LivingCreature class?

      public class Monster : LivingCreature

      If that doesn’t fix the problem, can you upload your solution (including the directories under it, and all the files in those directories) to GitHub or Dropbox, so I can look at it?

  15. Lucky
    Lucky November 26, 2018

    For Player, when I try to update the hit points, nothing changes. It just stays at zero.

    The gold, experience and level all changes to their different values, but hit points stays at zero. What can I do to fix this?

    • Scott Lilly
      Scott Lilly November 26, 2018

      Can you upload your solution (including the directories under it, and all the files in those directories) to GitHub or Dropbox, so I can look at it?

  16. Lucky
    Lucky November 27, 2018

    LINK REMOVED FOR PRIVACY

    The solution is just the .sln file, right? I’m new to Vs.

    • Scott Lilly
      Scott Lilly November 27, 2018

      I need all the files in that directory and its sub-directories (the .cs files, the xaml.cs files, the app.config, the PlayerData.xml files, etc.). It is probably easiest to compress the directory where you solution is (including its sub-directories) into a .zip file and upload that to Dropbox.

  17. Lucky
    Lucky November 28, 2018

    Ok, I zipped my entire project folder, so I should have all the files you needed.

    LINK REMOVED FOR PRIVACY

    • Scott Lilly
      Scott Lilly November 28, 2018

      There are two changes to make, to fix the problem.

      First, in the Player class, remove the “CurrentHitpoints” property. You shouldn’t need it, since the program needs to use the property from the base class (LivingCreature).

      Second, change line 25 of SuperAdventure,cs to the line below. This will make the program use the “CurrentHitPoints” property from LivingCreature class. Notice that the “P” was upper-case in LivingCreature, but lower-case “p” when it was in Player. That’s something to watch out for, since C# treats those as two different properties.

      lblHitPoints.Text = _player.CurrentHitPoints.ToString();

      Let me know if that doesn’t fix the problem, or if you have any other questions.

  18. Lucky
    Lucky November 29, 2018

    Thanks, that fixed it.

    I really need to learn to pay more attention. I was stuck for days on a problem that was fixable in under a minute.

    • Scott Lilly
      Scott Lilly November 29, 2018

      You’re welcome.

      As you write more programs, you’ll become faster at solving errors. You’ll start to build a mental library of problems, what usually causes them, and how to fix them. Then, people will think you’re a programming wizard. 🙂

  19. Glenn
    Glenn January 30, 2019

    Great tutorial.
    Small note – step 8 should say to change the Player constructor on line 28 (not line 23 – location code is lines 23-26 when I follow through the guide) and delete the lines 30 – 34. Just in case it confuses anyone 🙂
    Anyway, excellently clear guide so far. Thank you.

    • Scott Lilly
      Scott Lilly February 2, 2019

      Thanks Glenn,

      I think Visual Studio recently changed the default “using” lines at the beginning of the class (when it creates a new class). I’ve seen that from some other people. You might need to watch out for that in future lessons.

  20. Kebers
    Kebers August 20, 2019

    Hi Scott.

    Great tut. It is really fun to go through for somebody like me who is starting from scratch right here.

    I have a quick question though.

    In step 3, after the first part of the constructor, we are inheriting from “base”.
    “HealingPotion” inherits from “Item”, so am I correct in assuming “base” is just referencing “Item” since it is the base class? Or am I meant to have created a class called “base”?

    And a follow up to that, if “base” is just referencing “Item”, why don’t we just inherit from “Item” again?

    Lastly, this just confused me while going through this so I apologize for so many questions, why do we have to re-inherit? “HealinPotion” already inherits from “Item” and “Item” already has the “id”, “name” and “nameplural” properties.

    Thanks for any help on this.

    • Scott Lilly
      Scott Lilly September 23, 2019

      Hi Kebers,

      I’m sorry it’s taken so long to respond.

      Yes, the “base” in the constructor means the base class, which is the “Item” class (which was defined by saying “public class HealingPotion : Item”). When a child class constructor passes values to its parent class, you always do that by adding ” : base()” after the constructor. The compiler is smart enough to know “base” means “Item”, because we already declared HealingPotion’s parent as Item.

      For your last question, are you talking about passing the parameters into the HealingPotion constructor, but only using “amountToHeal” in the HealingPotion class – while passing the other parameters to the “base” (Item) constructor? If so, maybe think of this like this:

      Your neighbor asks you for a favor. He can’t go to the store, but needs some ingredients to cook dinner. He gives you a list of the things he needs (these equate to the parameters of the parent class). Your neighbor’s son (equating to the child class) is going to help you carry the items back, but he’ll only do that if you buy him a candy bar (the one “parameter” he cares about in his constructor. You and the son go to the grocery store, and you buy everything on your neighbor’s shopping list, plus a candy bar for the son. The son takes his candy and eats it – stores that parameter in his (the child class’) property. Then, he takes all the other items to his parent – the parameters needed by the parent class.

      That’s stretching the metaphor a bit, so let me know if it still isn’t clear.

Leave a Reply

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