I am trying to create a simple model. A vehicle can only ever have 1 VehicleType
, and a VehicleType
is a Vehicle
. As such I have created a base class Vehicle
, and three derived classes Bike
, Car
, and Truck
.
When I create the derived classes, is there anyway that I can force certain variables to always be the same for that class and not rely purely on the constructor? E.g., numberOfWheels
is always going to be 2 for a bike, and 4 for a car.. Is there anyway I can force declare that, or do I always have to declare them in the constructor? If I had multiple variables specific to that class, it just seems counter-intuitive to have to declare them individually and risk errors, when I can't help but think it would be so much easier to do it dynamically.
I have read the proposed duplicate, and I don't see how this answers the question. I am happy to be corrected, but please explain why - The duplicate question/answer only makes the base property read-only and would not solve my original question regarding variables that are common between all children and parent, but different for each class. I.e., all vehicles have wheels, however all bicycles only have 2 wheels; cars have 2, tricycles have 3, etc..
I am pretty new to this and would appreciate an answer in simple terms.
Welcome to the site. I think this is a great question and it illustrates some of the most powerful features of object oriented programming. And no you don't have to rely on the constructor.
abstract
classes and properties can be used to accomplish what you're looking for. To give a concise code example:
public enum VehicleType
{
Car,
Truck,
Bike
}
public abstract class Vehicle
{
public abstract VehicleType Type { get; }
public abstract int NumberOfWheels { get; }
}
public class Car : Vehicle
{
public sealed override VehicleType Type => VehicleType.Car;
public sealed override int NumberOfWheels => 4;
// Properties and methods specific to Car
}
public class Bike: Vehicle
{
public sealed override VehicleType Type => VehicleType.Bike;
public sealed override int NumberOfWheels => 2;
// Other properties and methods specific to Bike
}
// etc.
abstract
means the derived classes must implement the missing member by overriding it. So for each subclass of Vehicle
, in this example, you are forced to override Type
and return one of the VehicleType
values, and thus don't have to rely on the constructor (or a member that could be inadvertently changed elsewhere).
Adding the sealed
keyword also prevents subsequent subclasses of the individual vehicles from changing that property, so for example any class derived from Car (Sedan, Coupe, Roadster, etc) will always have 4 wheels.