Monday, 14 February 2011

Chapter 11 Inheritance in C#

As we had discussed earlier inheritance is one of the cornerstones of OOPS. Thus C# follows it too. You may have noticed that all framework classes inherit form one single class called Object. In this chapter we will look into the actual implementation aspect of inheritance.
STEP 1
To begin with lets design a simple Animal class.It will have three methods
  1. Constructor
  2. Talk
  3. Greet
Each one will print out a message with the Animal word included so that we know which class is responding to us
STEP 2
We will build another class called Dog and Donkey which will derive from Animal class . This class will have identical methods except the message printed will have the word Dog or Donkey included. Again to clarify which class is being executed.
using System;

namespace InheritanceSample
{
    class Animal
    {
        public Animal()
        {
            Console.WriteLine("I am an Animal Constructor");

        }

        public void Talk()
        {
            Console.WriteLine("Hi I am an Animal Talking");
        }

        public void Greet()
        {
            Console.WriteLine("Welcome from all Animals my friend");
        }
    }


    class Dog : Animal {
        public Dog()
        {
            Console.WriteLine("I am a DOG Constructor");
        }
        public void Talk()
        {
            Console.WriteLine("Hi I am a DOG Barking/Talking");
        }

        public void Greet()
        {
            Console.WriteLine("Welcome from all DOGS my friend");
        }
        
    }
    class Donkey : Animal {
        public Donkey()
        {
            Console.WriteLine("I am a DONKEY Constructor");
        }
        public void Talk()
        {
            Console.WriteLine("Hi I am a DONKEY Braying/Talking");
        }

        public void Greet()
        {
            Console.WriteLine("Welcome from all DONKEYS my friend");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Animal obj = new Animal();
            obj.Talk();
            obj.Greet();
            Console.ReadKey();
        }
    }
}


STEP 3
In the Main function we will declare an object of type Animal and it will reference an object of type Animal too. Then we call all the functions and output is shown below.
I hope this part of the output is clear.
STEP 4
Now we will change the code inside the Main function a bit and use the Dog class instead
The modified code only is given below
static void Main(string[] args)
 {
    Dog obj = new Dog();
    obj.Talk();
    obj.Greet();
    Console.ReadKey();
 }
The output is given below. Please note the first major difference. The Animal constructor gets called too and before the Dog constructor, this is a part of inheritance rule that the parents constructor will be called before the child's constructor. rest of all the output is I hope as you expected. You must notice that in this case all the child methods were called because the object type is Dog thus it calls all the child class methods.


STEP 5
Let us imagine we have many sub classes of Animal class and we decide to create an array of objects but what kind of array can we create, either it has to be Dog or Donkey or both. Instead of having separate arrays for each class we can declare an array of the base class, which can easily store objects of child class. Lets look at a simplified example, again only the code in then Main function is changed. We declare an object of type Animal and in it we reference an object of Dog type.
class Program
{
        static void Main(string[] args)
        {
            Animal obj = new Dog();
            obj.Talk();
            obj.Greet();
            Console.ReadKey();
        }
}
Following is the output


Did you see the difference even though Dog class constructor is called yet the methods of base class Animal are the one to execute. Why?..... Two reasons firstly the object type is Animal thus it will only call those methods which are defined inside the Animal class.This is a problem and beats the whole purpose of this exercise. Only way to overcome this is by overriding the base class method with that of the child class method. We will now tweak our class to do so. Only one of the function "Talk" will be changed, rest everything remains the same.
using System;

namespace InheritanceSample
{
    class Animal
    {
        public Animal()
        {
            Console.WriteLine("I am an Animal Constructor");

        }

        public virtual void Talk()
        {
            Console.WriteLine("Hi I am an Animal Talking");
        }

        public void Greet()
        {
            Console.WriteLine("Welcome from all Animals my friend");
        }
    }


    class Dog : Animal {
        public Dog()
        {
            Console.WriteLine("I am a DOG Constructor");
        }
        public override void Talk()
        {
            Console.WriteLine("Hi I am a DOG Barking/Talking");
        }

       
    }
    class Donkey : Animal
    {
        public Donkey()
        {
            Console.WriteLine("I am a DONKEY Constructor");
        }
        public override void Talk()
        {
            Console.WriteLine("Hi I am a DONKEY Braying/Talking");
        }

        public void Greet()
        {
            Console.WriteLine("Welcome from all DONKEYS my friend");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Animal obj = new Dog();
            obj.Talk();
            obj.Greet();
            Console.ReadKey();
        }
    }
}

Now look at the sample output and see how the base class talk function is called.

Notice the change in the Animal class function "Talk" it is now declared with the keyword virtual and the child class function "Talk" is declared with the keyword override. And I have removed the "Greet" method from Dog class.Yet the program will compile because the derived/child class inherits all the members of base class.
The override modifier is required to extend or modify the abstract or virtual implementation of an inherited method, property, indexer, or event.An override method provides a new implementation of a member inherited from a base class. The method overridden by an override declaration is known as the overridden base method. The overridden base method must have the same signature as the override method.
You cannot override a non-virtual or static method. The overridden base method must be virtual, abstract, or override.An override declaration cannot change the accessibility of the virtual method. Both the override method and the virtual method must have the same access level modifier.You cannot use the modifiers new, static, virtual, or abstract to modify an override method.An overriding property declaration must specify the exact same access modifier, type, and name as the inherited property, and the overridden property must be virtual, abstract, or override.
In a child constructor we can call any base class constructor using the syntax
public constructor()
:base(arguments)
{}
This will call the base class constructor, sometimes we may want to call the base class constructor which is not the default, in that case this syntax is helpful.
We can use the keyword base to call any parent class method with the following syntax base.methodname()

Polymorphism

Recall that polymorphism is the phenomenon where the same message sent to two different objects produces two different set of actions. Polymorphism is of two types static and dynamic or runtime polymorphism. To put simply if we declare two methods with the same name but different signature it is called method overloading and is a type of static polymorphism. While when we override any method it is called dynamic polymorphism or late binding.If we look at it a bit technically then we may define them as
Static polymorphism refers to an entity existing in different physical forms simultaneously. Static polymorphism involves binding of functions based on the number, type, and sequence of arguments. The various types of parameters are specified in the function declaration, and therefore the function can be bound to calls at compile time. This form of association is called early binding. The term early binding stems from the fact that when the program is executed, the calls are already bound to the appropriate functions.
With runtime polymorphism(Dynamic polymorphism), the selection of a method for execution is based on the actual type of the object whose reference is stored, and not on the type of the reference variable on which the method is invoked.
All the programs given above are example of dynamic polymorphism.
Static Polymorphism example can be any method/function which is defined multiple time in the same class with different signature.

No comments:

Post a Comment