C# Tutorial : Lesson 13 – Inheritance – Part II

Partho Sarathi

21 Mar, 2009 · 6 minutes read

  • Share:
Abstract Class

Consider the term Vehicle. It does not have an existence of its own. However, types of vehicles; namely, Car, Aeroplane, Bus, etc do. Similarly, we can have Abstract classes which cannot be instantiated thus exhibiting the abstract behavior. They merely contain the skeleton of the class but not its implementation. The abstract keywordis used to declare such a class.

abstract class Vehicle
{

}

static void Main(string[] args)
{
    // Abstract Class cannot be instantiated
    Vehicle obj = new Vehicle();    // Shows Compilation Error.
}
Abstract Methods

Abstract methods contain the function signature and return type, but no body. A child class can override the abstract method thus providing its implementation. Abstract methods are also declared by using the abstractkeyword.

abstract class Vehicle
{
    public abstract void Run();
}

class Car : Vehicle
{
    public override void Run()
    {
        Console.WriteLine("Run the Car");
    }
}

class Bus : Vehicle
{
    public override void Run()
    {
        Console.WriteLine("Run the Bus");
    }
}

In this example, the abstract method Run() is declared in the Vehicle class. Notice the lack of the { } braces which marks the lack of a body. Since the Vehicle class cannot be instantiated, it does not need to have an implementation for the Run() method. The actual implementation is contained in its derived classes – Car, Bus. Thus, the abstract class only forms the skeleton of the child classes which exhibit specialization by overriding and implementing the abstract methods.

Note: Abstract methods can only be defined inside an abstract class.

Overriding Methods

In the previous example the overridekeyword is used. A parent class method can be overridden by a child class. In this way it provides its own implementation shadowing the one of the base class. A method must be declared as abstractor virtualto be overridden inside the child class.

Virtual Functions

The difference between a virtual function/method and an abstract method is that while the latter does not provide an implementation, the former does. If a virtual function of the parent class is not overridden, the method is inherited as it is, inside the child class. Again, we use the virtualkeyword for declaring virtual functions.

The following example shows various cases when a method can/cannot be overridden.

abstract class Vehicle
{
    // Abstract Method. Contains no body.
    public abstract void Run();
}

class Car : Vehicle
{
    // Abstract method is overridden.
    public override void Run()
    {
        Console.WriteLine("Run the Car");
    }

    // Normal Method. Cannot be overridden.
    public void Brake()
    {
        Console.WriteLine("Stop the Car");
    }

    // Virtual Method. Can be overridden.
    public virtual void Accelerate()
    {
        Console.WriteLine("Step on the gas");
    }
}

class BMW : Car
{
    // An overridden method can be further overridden.
    public override void Run()
    {
        Console.WriteLine("Run the BMW");
    }

    // Shows Compilation Error.
    // The Brake method of Car is
    // not declared as virtual or abstract.
    public override void Brake()
    {
        Console.WriteLine("Stop the Car");
    }

    // Virtual method is overridden.
    public override void Accelerate()
    {
        Console.WriteLine("Step on the gas");
    }
}

From the following you can deduce that for a method to be overridden, it must be declared as abstractor virtual. An overridden method can be further overridden because it carries over the virtual modifier.

Sealed Classes

So many ways to modify a class but none to protect? Fear not, sealedclasses are here to the rescue. This modifier prevents a class from being tampered by not allowing other classes to inherit from it.

sealed class Ferari
{

}

// Shows Error. Cannot inherit from sealed class.
class McLaren : Ferari
{

}
Sealed Methods

Use the sealed modifier to prevent a method from being overridden. Normally, you do not need to use this modifier as the methods are not overridable by default. However, if you want to protect an overridden method from being further overridden, you should use the sealed method instead of sealing off the entire class.

Interfaces

Remember that C# does not support multiple inheritance? Multiple inheritance tends to cause more problems than it solves. However, the ability to derive methods and properties from multiple sources is present in C#. This is done using Interfaces. Interfaces only contain the declaration part of a class. The actual definition which comprises of the body of the method is present inside the class which implements the interface.

Declaring Interfaces

They are declared similar to how classes are. Only differences are that they can only contain methods and properties (no variables), they do not contain the definition for these methods/properties and off-course the interface keyword.

interface Flyer
{
	public void Fly();
}
Implementing Interfaces

Classes do not inherit from interfaces, rather implement them. Although, the process of doing this is the same.

class Aeroplane : Flyer
{

}

Multiple interfaces can be implemented as follows:-

class Aeroplane : Flyer, Vehicle
{

}

Here, Vehicle is also assumed to be an interface.

A class can inherit from another class and implement an interface in a similar fashion:-

class Bird : Mammal, Flyer
{

}

Note: Mammal is a class here.

Inheriting Interfaces

Interfaces themselves can inherit from other interfaces. Again, the process is the same.

interface MechanicalFlyer : Flyer
{

}
Why use interfaces?

Interfaces provide the skeletal structure of the classes which implement them. They separate the definition of objects from their implementation.

Why not just use Abstract classes?

Abstract classes are meant to be used when you want only some of the methods/properties to be implemented by the sub class. Besides, a class cannot inherit from multiple classes but it can implement multiple interfaces.

The following example depicts the need for interfaces.

abstract class Animal
{
	public void Eat()
	{
	}
}

abstract class Vehicle
{
	public void Run()
	{
	}
}

interface Flyer
{
	public void Fly();
}

class Aeroplane : Vehicle, Flyer
{

}

class Bird : Animal, Flyer
{

}

As you can see, the two sub classes Bird and Aeroplane derive from the Animal and Vehicle classes respectively. Both have the characteristics of their respective base classes. The Bird like any other animal, eats while the Aeroplane being a vehicle, runs. However, they both share a common trait – the ability to fly. This ability is neither possessed by all animals nor by all vehicles. So it cannot be defined in either of the base classes. Again, it is not only possessed by the Aeroplane and Bird, some insects, baloons and other types of vehicles such as the Helicopter also possess it. It wouldn’t be effective to define this ability in each of them. Actually, it will be defined individually in each of these classes because each have their own way of flying, the bird flaps the wings, whereas the helicopter roatates its through a mechanical engine. However, this ability is declared in the Flyer interface so that any class which implements this interface would have to define the Fly() method by overriding it.

  • Share:

The cleanest blogging platform


2024 © Maxotek. All rights reserved.