PorkchopDonut PorkchopDonut - 17 days ago 10
C# Question

Using instantiated class members as variables in abstract class methods

I'm trying to figure out how to make a method in a base abstract class capable of using member values of instantiated objects derived from the class. For example, let's say I have a class called

Vehicle
that inherits an interface called
IVehicle
;

public abstract class Vehicle : IVehicle
{
public int Wheels = 4;

public int CountWheels()
{
return Wheels;
}
}


Let's say I then had another class called
Motorcycle
that inherited
Vehicle
as such;

public class Motorcycle : Vehicle, IVehicle
{
public int Wheels = 2;
}


If I make a new
Motorcycle
called
newMotorcycle
and I call
newMotorcycle.CountWheels()
, I get 4 instead of 2. I'm assuming this is an issue with my
Wheels
definition in the
Motorcycle
class, but I've tried just about everything I can think of to get this to work and it always seems to want to ignore child class definitions. I know that I could make the
CountWheels()
method abstract and define it in the
Motorcycle
class, but I'm trying to keep the base
Vehicle
class as generic as possible so I can implement a ton of other child classes without having to redefine the same method over and over.

My first question; is what I'm trying to do even possible? If so, what part of my member definition needs to change for this to work the way I'm intending for it to?

I promise I scoured the internet before I posted this here and I couldn't find enough information to help myself...

Answer

You will notice that there is a warning in the code you posted:

Motorcycle.Wheels hides inherited member Vehicle.Wheels...

Hence your problem, Vehicle has no idea that a derived class has hidden one of its members (hence why hiding is a bad idea).

Since you can't have virtual fields, you should change it to a virtual (or in this case, abstract so everyone has to define it) property:

public abstract class Vehicle : IVehicle
{
    public abstract int Wheels {get;}

    public int CountWheels()
    {
        return Wheels;
    }
}

public class Motorcycle : Vehicle, IVehicle
{
    public int Wheels => 2;
}

Now every derived class will have to have a Wheels property that the base class can use.