BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

C# Programming
.NET 1.1+

C# Inheritance

The eighteenth part of the C# Object-Oriented Programming tutorial begins the discussion of the use of inheritance. This is a powerful object-oriented concept that permits the creation of hierarchical groups of classes that share common functionality.

Polymorphism and Inheritance

Polymorphism is an important object-oriented programming concept. Polymorphism is the ability for an object to change its public interface according to how it is being used. When using inheritance, polymorphism is achieved when an object of a derived class is substituted where an instance of its parent class is expected. This uses a process known as upcasting. With upcasting, the object of the more specialised class is implicitly cast to the base class type required.

In the case of the MotorVehicle and Bicycle class, instances of either type can be held within a Vehicle variable or passed as a Vehicle method parameter. Any users of the object will only have access to the public interface defined by the base class but when these members are accessed, the underlying members of the derived class will be executed. So if we require a standard routine to operate on any type of vehicle, we can use a Vehicle variable in the knowledge that internally the subclass's functionality will run.

To demonstrate this, we will create some basic Vehicle variables but assign MotorVehicle or Bicycle objects to them. We can then observe the results, as in the following modified Main method:

Vehicle car = new MotorVehicle();
Vehicle bike = new Bicycle();
car.Indicate(true);
bike.Indicate(true);

/* OUTPUT

Flashing left indicator
Turning left
Raising left arm

*/

Another way of demonstrating this polymorphism behaviour is to use a method in the Program class. The method shown below accepts a Vehicle parameter that can be substituted with a MotorVehicle or Bicycle.

static void Main(string[] args)
{
    Vehicle car = new MotorVehicle();
    Vehicle bike = new Bicycle();

    IndicateLeft(car);
    IndicateLeft(bike);

    /* OUTPUT

    Flashing left indicator
    Turning left
    Raising left arm

    */
}

static void IndicateLeft(Vehicle vehicle)
{
    vehicle.Indicate(true);
}

As can be seen from the previous examples, the conversion between a child class and its parent is performed implicitly. The reverse is not true. If, for example, a Vehicle variable contained a MotorVehicle object, it could not be assigned directly to a MotorVehicle variable. In this case, an explicit cast would be required as shown below:

Vehicle car = new MotorVehicle();
MotorVehicle theCar = (MotorVehicle)car;    // Explicit cast

This explicit casting to a more specialised class is the opposite of the upcasting concept described earlier. As such, it is known as downcasting.

Name Hiding

Name hiding is a similar concept to overriding. With name hiding, a new version of a member or variable is created in a child class to replace or extend the parent's version. However, rather than using the override keyword, the new keyword prefixes the declaration.

The main functional difference between name hiding and overriding is that the polymorphism effect is lost. When a derived class instance is assigned to a variable of the base class type, the functionality of the base class member is executed rather than the functionality of the method causing the name hiding.

Name hiding is useful if you do not have control over a base class. This may be because it is part of a library for which you do not own the source code. If a member of a base class is not marked as virtual then you may not override it. However, even non-virtual members may be hidden.

In the next example, the MotorVehicle's Indicate method is replaced using name hiding rather than overriding. Note the effect of calling the method differs according to the data type of the variable that the object resides within. To demonstrate, first modify the Indicate method of the MotorVehicle class as follows:

public new void Indicate(bool turningLeft)
{
    if (turningLeft)
        Console.WriteLine("Flashing left indicator");
    else
        Console.WriteLine("Flashing right indicator");
}

Now modify the Main method and execute it to see the results. You can see that the output is different in each call to the Indicate method, something that does not occur with method overriding:

Vehicle car1 = new MotorVehicle();
car1.Indicate(true);                        // Outputs "Turning left"

MotorVehicle car2 = new MotorVehicle();
car2.Indicate(true);                        // "Flashing left indicator"

NB: After testing the above sample, revert the Indicate method to use override rather than new.

15 March 2008