Question Inheritance: What am I doing wrong?

glasswizzard

Well-known member
Joined
Nov 22, 2019
Messages
126
Programming Experience
Beginner
I must be misunderstanding inheritance because I want to do a simple thing but it doesn't work. Let's say I have a base class like so:

C#:
public class BaseClass
{
    int num1 = 0;
    int num2 = 0;
    int num3 = 0;
  
    public BaseClass(int a, int b, int c)
    {
        num1 = a;
        num2 = b;
        num3 = c;
    }
  
    public int Calculate()
    {
        return num1+num2+num3;
    }
}

Now let's say I envision the use for a class like so:

C#:
public class NewClass
{
    int num1 = 0;
    int num2 = 0;
    int num3 = 0;
    int num4 = 0;
  
    public NewClass(int a, int b, int c, int d)
    {
        num1 = a;
        num2 = b;
        num3 = c;
        num4 = d;
    }
  
    public int Calculate()
    {
        return num1 + num2 + num3 + num4;
    }
}

It's the same class but with one extra variable. From what I've learned of inheritance this seems to be the perfect situation to use it. The second class can inherit from the first and just add that one new variable right? The way I tried to do it (which does not work) was like so:

C#:
public class NewClass : BaseClass
{
    int num4 = 0;
  
    public NewClass(int a, int b, int c, int d)
    {
        num1 = a;
        num2 = b;
        num3 = c;
        num4 = d;
    }
  
    public int Calculate()
    {
        return num1+num2+num3+num4;
    }
}

That inherited class doesn't seem to know it has the variables from the old class and says they don't exist in this context.

So am I doing something wrong? Do I not understand how/why inheritance is used?
 
Last edited:
There's two issues:
1) You'll need to declare num1, num2, and num3 as protected for the descendants to see them.
2) The NewClass should call the BaseClass constructor by using base. Check out the Book class in the MSDN docs.
 
Last edited:
If you want the derived class to be able to access the fields of the base class then, as suggested, they should be declared protected. You really ought to provide an access modifier for EVERY type and EVERY member. Each kind of member has a default access level in each kind of type but, unless you know them by heart and expect all readers of your code to as well, you should be explicit. If you actually want private fields then declare them private, but otherwise specify the access level you do want.

That said, in this case, there's probably a better way. Rather than the derived class accessing those fields directly, it could simply use the base Calculate method. If you declare that method as virtual then you can simply override it, use the base result and then tack on the additional functionality. If you don't want that base functionality to ever change, e.g. you'd never want the derived class to multiply those fields rather than add, then that is a good option. By overriding the method, you are guaranteed to invoke the derived implementation, even if it is called via a reference of the base type.
C#:
public class BaseClass
{
    private int num1 = 0;
    private int num2 = 0;
    private int num3 = 0;

    public BaseClass(int a, int b, int c)
    {
        num1 = a;
        num2 = b;
        num3 = c;
    }

    public virtual int Calculate()
    {
        return num1 + num2 + num3;
    }
}

public class NewClass : BaseClass
{
    private int num4 = 0;

    public NewClass(int a, int b, int c, int d) : base(a, b, c)
    {
        num4 = d;
    }

    public override int Calculate()
    {
        return base.Calculate() + num4;
    }
}
By the way, while it doesn't actually hurt, there's no point initialising those fields where they're declared when they are guaranteed to be set in the constructor.
 
Last edited:
I just made a correction to my previous post. This:
By overriding the method, you are guaranteed to invoke the base implementation, even if it is called via a reference of the base type.
should have been this:
By overriding the method, you are guaranteed to invoke the derived implementation, even if it is called via a reference of the base type.
 
Back
Top Bottom