Saturday, May 3, 2014

Inheritance in C#, Method hiding and Late binding ,Polymorphism

Inheritance is a mechanism of acquiring the features and behaviors of a class by another class. The class whose members are inherited is called the base class, and the class that inherits those members is called the derived class. Inheritance implements the IS-A relationship.
For example, mammal IS-A animal, dog IS-A mammal; Hence dog IS-A animal as well.
Advantages
1.       Reduce code redundancy.
2.       Provides code reusability.
3.       Reduces source code size and improves code readability.
4.       Code is easy to manage and divided into parent and child classes.
5.       Supports code extensibility by overriding the base class functionality within child classes.
Disadvantages
1.       In Inheritance base class and child classes are tightly coupled. Hence If you change the code of parent class, it will get affects to the all the child classes.
2.       In class hierarchy many data members remain unused and the memory allocated to them is not utilized. Hence affect performance of your program if you have not implemented inheritance correctly.
  1. Single Inheritance
  2. Hierarchical Inheritance
  3. Multi Level Inheritance
  4. Hybrid Inheritance
  5. Multiple Inheritance
1.  Single Inheritance

when a single derived class is created from a single base class then the inheritance is called as single inheritance.


Description: Different types of inheritance

Single Inheritance Example Program

2. Hierarchical Inheritance

when more than one derived class are created from a single base class, then that inheritance is called as hierarchical inheritance.

Description: Hierarical Inheritance


3. Multi Level Inheritance

when a derived class is created from another derived class, then that inheritance is called as multi level inheritance.

Description: Multi level Inheritance


4. Hybrid Inheritance

Any combination of single, hierarchical and multi level inheritances is called as hybrid inheritance.


Description: Hybrid inheritance in C#


5. Multiple Inheritance

when a derived class is created from more than one base class then that inheritance is called as multiple inheritance. But multiple inheritance is not supported by .net using classes and can be done using interfaces.

Description: Multiple inheritance in C#

  
Multiple Inheritance Example

Handling the complexity that causes due to multiple inheritance is very complex. Hence it was not supported in dotnet with class and it can be done with interfaces.

Why C# does not support multiple Inheritance
There is the classic diamond problem encountered in multiple inheritance, in which class D inherits from both B and C, which both inherit from A.
  A
 / \
B   C
 \ /
  D
So which copy of A does D get? The one from B, the one from C? Both? This way various languages resolve this problems is discussed here:
It is informative, if a bit dizzying, to read the last sentence in the explanation of the way C++ resolves this issue.
It has CalcualteArea method
Class Shape1
{
     public void CalculateArea()
     {
       //
     }
}

There is another class shape2 that one also has same method 
Class Shape2
{
     public void CalculateArea()
     {
       //
     }
}

Now i have a child class Circle, it derives from both SHape1 and shape2;

public class Circle: Shape1,shape2
{
}


Now when i create object for Circle, and call the method, system doesnt know which calculate area method to be called.. Both has same signatures. So compiler will get confuse .thats why multiple inheritances are not allowed.

But there can be multiple interfaces because interfaces dont ve methjod definition..Even both the interfaces have same method, both of them dont ve any implementation and always method in the child class will be executed..

****************************************************************************************************************************

1.Inheritance 
2.Method Hiding
3.Polymorphism


Withe Inheritance we can get the parent class information(that parent class wants to be inherited not private) into Child class So

Class Parent
{
public void A(){}

class Child :Parent
{

}
class Program
{
main()
    {
       Child c=new Child()
       c.A(); //Becoz of inheritance, 
If now child wants his own implimentation A(). Then use new if method name is same
      
    }
}
See below example.

    class Employee
    {
        string firstname;
        string lastname;
        public string Firstname { get { return firstname; } set { firstname = value; } }
        public string Lastname { get { return lastname; } set { lastname = value; } }
        public  void PrintName()
        {
            Console.WriteLine("EmployeeName is"+firstname+" "+lastname );
        }
         void PrintName1() //private method
        {
            Console.WriteLine("EmployeeName is" + firstname + " " + lastname);
        }
    }
    class PartTimeEmployee : Employee
    {
        public new void PrintName()
        {
            Console.WriteLine("Part time Employee Name is" + Firstname + " " + Lastname);
        }
    }
    class FullTimeEmployee : Employee
    {      
  
    }
    class A
    {
        public static void Main()
        {
            PartTimeEmployee prt = new PartTimeEmployee { Firstname = "Anil", Lastname = "sharma" };
            prt.PrintName();
            FullTimeEmployee fte = new FullTimeEmployee { Firstname = "Amit", Lastname = "sharma" };
            fte.PrintName();
           //Now there is req that when client see the employee name than he can identify that user is part time or full time. so in specialize class while printinfg name we will add to identify it
            PartTimeEmployee prt1 = new PartTimeEmployee { Firstname = "Anil", Lastname = "sharma" };
            prt1.PrintName(); //but warning is coming saying that child class Printname method hides the inherited base class method. So to overcome this we will add " new " keyword



            FullTimeEmployee fte1 = new FullTimeEmployee { Firstname = "Ram111111", Lastname = "sharma" };
            ((Employee)fte1).PrintName();
            Employee e = new FullTimeEmployee();
           // e.PrintName1();//not coming
            e.PrintName();
            //Here Child class has all information of own and all information that is inherited from base. So we can convert it Base type and can call any of base class method that inherited not the private one

            Employee emp = new Employee { Firstname="K",Lastname="M"};
            FullTimeEmployee f = (FullTimeEmployee)emp;
           //But when we create BAse class object and try to cast in to Child class than you can not you have to explicit cast so that you will no get ay compiple time error but at run time u will egt invalid cast exception.Why because base has its own inofrmation not of child so it become incomplete obj and reference of child will not find any information of its own in base type object.

            
            Console.Read();
        }

    }




namespace KudVenkatCsharp
{
    class Employee1
    {
        string firstname;
        string lastname;
        public string Firstname { get { return firstname; } set { firstname = value; } }
        public string Lastname { get { return lastname; } set { lastname = value; } }
        public void PrintName()
        {
            Console.WriteLine("EmployeeName is" + firstname + " " + lastname);
        }
       void BaseClassPrivatefunction()
        {
            Console.WriteLine("EmployeeName is" + firstname + " " + lastname);
        }
    }
    class PartTimeEmployee1 : Employee1
    {
        public string MiddleName { get; set; }
        public new void PrintName()
        {
            Console.WriteLine("Part time Employee Name is" + Firstname + " " + MiddleName+ " "+ Lastname);
        }
        public void PrintFullName()
        {
            Console.WriteLine("Part time Employee Full name  is" + Firstname + " " + MiddleName + " " + Lastname);
        }
    }
    class FullTimeEmployee1 : Employee1
    {
        public  new void PrintName()
        {
            Console.WriteLine("full time Employee Name is" + Firstname + " " + Lastname);
        }
    }
    class TempEmployee1 : Employee1
    {
        public  new void PrintName()
        {
            Console.WriteLine("Temp time Employee N

ame is" + Firstname + " " + Lastname);
        }
    }
    public class Program11
    {
        public static void Main()
        {
            PartTimeEmployee1 p = new PartTimeEmployee1 { Firstname = "A_PartTimeEmployee1", Lastname = "B_PartTimeEmployee1", MiddleName = "PartTimeMiddlename" };
            p.PrintName();
            p.PrintFullName();

            Console.WriteLine("****************************************");
            Console.WriteLine("****************Always Base class verion called.************************");

            Employee1 emp1 = new Employee1 { Firstname = "A_base", Lastname = "B_base" };
            emp1.PrintName();
            Employee1 emp2 = new PartTimeEmployee1 { Firstname = "A_PartTimeEmployee1", Lastname = "B_PartTimeEmployee1", MiddleName = "PartTimeMiddlename" };
            emp2.PrintName();

            /*
             Base class refernce ojb can point only its  information that are inherited from base to derived only not base private too. In below we base class ref obj pointing to Child that is accecepted.
             * Here Child class has all information of own and all information that is inherited from base. So we can convert it Base type and can call any of base class method that inherited not the private one.
             * Child class object can ful fill all the responsibility of Parent Class. Parent class object can not ful fill all the res of Child CLass.
             * So base class ref can only see its own class function and even though we are having same function in child but still base class ref is calling base class PrintNAme() function. 
             */
         //   emp2.PrintFullName();//It is compile time error becoz that information is in Child class obj and only child class ref obj can point to
           // emp2.BaseClassPrivatefunction();//Giving error becoz that is not inherited into child.
            Employee1 emp3 = new FullTimeEmployee1 { Firstname = "A_FullTimeEmployee1", Lastname = "B_FullTimeEmployee1" };
            emp3.PrintName();
            Employee1 emp4 = new TempEmployee1 { Firstname = "A_TempEmployee1", Lastname = "B_TempEmployee1" };
            emp4.PrintName();

            Console.WriteLine("****************************************");
            Console.WriteLine("****************Always Base class verion called.************************");

            Employee1[] emp = new Employee1[4];
            emp[0] = new Employee1 { Firstname = "A_base", Lastname = "B_base" };
            emp[0].PrintName();
            emp[1] = new PartTimeEmployee1 { Firstname = "A_PartTimeEmployee1", Lastname = "B_PartTimeEmployee1", MiddleName = "PartTimeMiddlename" };
            emp[1].PrintName();
            emp[2] = new FullTimeEmployee1 { Firstname = "A_FullTimeEmployee1", Lastname = "B_FullTimeEmployee1" };
            emp[2].PrintName();
            emp[3] = new TempEmployee1 { Firstname = "A_TempEmployee1", Lastname = "B_TempEmployee1" };
            emp[3].PrintName();

            Console.WriteLine("****************************************");
            /*
             * So if we want that base class ref obj will point to derived class version So it shud be overriden into the child class and  Base class function shud mark as Virtual.
             */ 
            Console.Read();



        }

    }
}


OUT PUT
Part time Employee Name isA_PartTimeEmployee1 PartTimeMiddlename B_PartTimeEmplo
yee1
Part time Employee Full name  isA_PartTimeEmployee1 PartTimeMiddlename B_PartTim
eEmployee1
****************************************
****************Always Base class verion called.************************
EmployeeName isA_base B_base
EmployeeName isA_PartTimeEmployee1 B_PartTimeEmployee1
EmployeeName isA_FullTimeEmployee1 B_FullTimeEmployee1
EmployeeName isA_TempEmployee1 B_TempEmployee1
****************************************
****************Always Base class verion called.************************
EmployeeName isA_base B_base
EmployeeName isA_PartTimeEmployee1 B_PartTimeEmployee1
EmployeeName isA_FullTimeEmployee1 B_FullTimeEmployee1
EmployeeName isA_TempEmployee1 B_TempEmployee1
****************************************
********************************************************************

Polymorphism

namespace KudVenkatCsharp1
{
    class Employee1
    {
        string firstname;
        string lastname;
        public string Firstname { get { return firstname; } set { firstname = value; } }
        public string Lastname { get { return lastname; } set { lastname = value; } }
        public void PrintName()
        {
            Console.WriteLine("EmployeeName is" + firstname + " " + lastname);
        }
        void BaseClassPrivatefunction()
        {
            Console.WriteLine("EmployeeName is" + firstname + " " + lastname);
        }
        public virtual void PrintfullName()
        {
            Console.WriteLine("EmployeeName is" + firstname + " " + lastname);
        }
    }
    class PartTimeEmployee1 : Employee1
    {
        public string MiddleName { get; set; }
        public new void PrintName()
        {
            Console.WriteLine("Part time Employee Name is" + Firstname + " " + MiddleName + " " + Lastname);
        }
        public void PrintFullName()
        {
            Console.WriteLine("Part time Employee Full name  is" + Firstname + " " + MiddleName + " " + Lastname);
        }
        public override void PrintfullName()
        {
            Console.WriteLine("Part time  PrintfullName Employee Name is" + Firstname + " " + MiddleName + " " + Lastname);
        }
    }
    class FullTimeEmployee1 : Employee1
    {
        public new void PrintName()
        {
            Console.WriteLine("full time Employee Name is" + Firstname + " " + Lastname);
        }

        public override void PrintfullName()
        {
            Console.WriteLine("full time PrintfullName Employee Name is" + Firstname + " " + Lastname);
        }
    }
    class TempEmployee1 : Employee1
    {
        public new void PrintName()
        {
            Console.WriteLine("Temp time Employee Name is" + Firstname + " " + Lastname);
        }

      
    }
    public class Program11
    {
        public static void Main()
        {
            Console.WriteLine("****************************************");
            Console.WriteLine("****************Always Base class verion called.************************");

            Employee1[] emp = new Employee1[4];
            emp[0] = new Employee1 { Firstname = "A_base", Lastname = "B_base" };
            emp[0].PrintName();
            emp[1] = new PartTimeEmployee1 { Firstname = "A_PartTimeEmployee1", Lastname = "B_PartTimeEmployee1", MiddleName = "PartTimeMiddlename" };
            emp[1].PrintName();
            emp[2] = new FullTimeEmployee1 { Firstname = "A_FullTimeEmployee1", Lastname = "B_FullTimeEmployee1" };
            emp[2].PrintName();
            emp[3] = new TempEmployee1 { Firstname = "A_TempEmployee1", Lastname = "B_TempEmployee1" };
            emp[3].PrintName();
            Console.WriteLine("****************************************");
            foreach (Employee1 e in emp)
            {
                e.PrintName();
            }
            Console.WriteLine("****************************************");
            Console.WriteLine("***************After Marked Base virtual and child ovverride now with base class ref  we can call specialed ovevriredin finction*************************");

            foreach (Employee1 e in emp)
            {
                e.PrintfullName();
            }

            //For TempEmployee1 class we did not give any ovveriden function than in this case base class Virtual gets called.

            Console.Read();



        }

    }
}


Difference between Method Hiding and Overriding










  class Base
    {
        public virtual void show() { Console.WriteLine("Base class show"); }
        public virtual void show1() { Console.WriteLine("Base class show"); }
    }
    class Derived : Base { public new void show() { Console.WriteLine("Derived class show"); } 
        public override  void show1() { Console.WriteLine("Derived class show"); } }//warning is coming
    class Program 
    {
        public static void Main()
        {
            Base b = new Derived();
            b.show(); //This will call base class version method hiding,To call child class u shud ovveride this method in child class
            b.show1();//Calling Child class overriden function 
            Console.ReadLine();
        }


    }

**********************************************************************************************************
class OutExample
    {
        static void Method(out int i,int m)
        {
            i = 44;// Although variables passed as out arguments do not have to be initialized before being passed, the called method is required to assign a value before the method returns.

        }
        static void Main()
        {
            int value;
            int m = 9;
            Method(out value, m);
            // value is now 44
        }
    }
class RefExample
    {
        static void Method(ref int i)
        {
            // Rest the mouse pointer over i to verify that it is an int. 
            // The following statement would cause a compiler error if i 
            // were boxed as an object.
            i = i + 44;
        }
 
        static void Main()
        {
            int val = 1;
            Method(ref val);
            Console.WriteLine(val);
 
            // Output: 45
        }
    }
********************************************************************


public class MyClass
    {
        public string Name { get; set; }
        public void Foo(ref MyClass someObject)//The actual reference to someobject gets sent to the method
        {
            MyClass myTempObject = new MyClass();
            myTempObject.Name = "Cat";
            someObject = myTempObject;
            Console.WriteLine("Inside Fun" + someObject.Name);//dog
            Console.WriteLine(someObject.Name); // Writes "Dog".
        }
        public void Bar(MyClass someObject)//different ref pointer will hold old memory block, copies old ref pointer to new ref pointer
        {
            MyClass myTempObject = new MyClass();
            myTempObject.Name = "Cat";
            someObject = myTempObject;//and scope is limited , where it is declared , only in this function block
            Console.WriteLine("Inside Fun" + myTempObject.Name);//dog
            Console.WriteLine(someObject.Name); // Writes "Dog".
        }
        public static void Main(string[] args)
        {
            MyClass myObject = new MyClass();
            myObject.Name = "Dog";
            Console.WriteLine("Outside Fun" + myObject.Name);//dog
            myObject.Bar(myObject);
            Console.WriteLine("After coming from Fun" + myObject.Name);//dog
            Console.WriteLine(myObject.Name);//dog
            myObject.Foo(ref myObject);
            Console.WriteLine(myObject.Name);//cat
            Console.ReadLine();
        }
    }
 
**************************************************************
Polymorphism


Upcasting is basically an object creation mechanism in which we create objects by referring to their base class. We do this by replacing the sub-class by the base-class in the object definition. This particularly comes in handy when you know that a specialized object created will not necessarily use all the functions that it has got to offer. So, replace a subclass(inherited class) by a base-class and all you have done is Upcasting.
Description: https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjcBIfc3mhVgFLm00X55aO4Ymm9Qfygym3p_Aj0dVLFntG1YyEGUdxvaPdGFYw6M-VCs-X8uG9a9Uf7kdoaALFibnBV3lizfevOn7B2-4qP4xHAGdnMMQ3ANcG5Qmegkxx2WH8_80ryjaE/s1600/Upcasting+Downcasting+C%23.png
This concept can be well understood if we take an example. Lets suppose we have three classes. One parent or generalized class called the LIVING_THINGS class and the two subclasses ANIMAL and BIRD which inherit from the former. The parent class or the baseclass has the function, say Born()and Die(). The specialized class have the function, say Run() and Fly() for ANIMAL and BIRD respectively. To create an ANIMAL and BIRD object you would usually use the syntax below:
  • ANIMAL animal = new ANIMAL();
  • BIRD bird = new BIRD();  
In the code above, the methods Run()and Fly() work perfectly with the objects created. This is the normal way in which you would create the objects. The reference used to create the object is exactly the same as the object type created during run-time. The methods of the subclass work just fine.  But, to create an Upcast, you would use the syntax below:
  • LIVING_THINGS animal = new ANIMAL();
In the code above, even though we have created an object of the type ANIMAL and BIRD, the reference used is actually of the base-class. Therefore the methods Run() and Fly() are not available to these objects. Instead only the functions available in the base-class such as Born() and Die() are available. This can be useful if you want only basic functions available at the start and want to later convert these objects of their original types to make their specialized functions available afterwards. This can be done with the help of Downcasting. Downcasting can change the reference types of these objects to the specialized subclass to make available the functions which were not available otherwise. Watch the code below:
  • ANIMAL new_animal  = animal as ANIMAL;
In the above code, we have created a new object and converted it to an ANIMAL type. It should be a good practice to actually check if the object to be converted supports the conversion. This can be done with the help of the is keyword if (animal is ANIMAL) {      ANIMAL new_animal  = animal as ANIMAL;      new_animal.Run(); With the help of Downcasting, we have restored all the functions and properties that the ANIMAL object should have. Now it behaves as a proper ANIMAL object.
A characteristic feature of inheritance is that an object of a publicly derived class can be used as an object of its corresponding base class. Note, however, that the reverse is not true; objects of the base class cannot be used as objects of its derived class
This is a powerful feature because it provides a mechanism for handling objects of different types in arrays, or accessing objects of different types through one pointer or reference
The following are standard conversions for derivation:
Only apply to publicly derived base classes
A derived class object will be implicitly converted to a public base class object
A derived class reference will be implicitly converted to a public base class reference
A derived class pointer will be implicitly converted to a public base class pointer
A pointer to any class object will be implicitly converted to a void* pointer
Consider the following example:
class Vehicle{
     // Vehicle members go here
};
class Car : public Vehicle{
     // Car members go here
};
class Truck : public Vehicle{
     // Truck members go here
};
Vehicle v1;
Vehicle* vPtr;
Car* cPtr;
Car c1;
Truck t1;
v1 = c1; // Valid because a Car is a special type of Vehicle
vPtr = &t1; // Valid because a Truck is a special type of Vehicle
cPtr = &v1; // Not Valid because v1 may not be a Car!!
class Shape{
public:
        int calcDistance(Shape& otherShape);
        ...
};
class ClosedShape : public Shape{ ... };
class Polygon : public ClosedShape { ... };
int main()
{
        Shape* sh1;
        ClosedShape* cs1;
        Polygon* poly1 = new Polygon;
        Polygon* poly2;
        Polygon Poly3;
        cs1 = poly1;           // Valid, upcasting Polygon to ClosedShape
        sh1 = poly1;           // Valid, upcasting Polygon to Shape 
        poly2 = cs1;           // Invalid, downcasting ClosedShape to Polygon
                               // Explicit clast is required to downcast
        poly2 = (Polygon*) cs1; // Valid downcast with explicit cast
        poly3.calcDistance(*cs1); // Valid, implicit upcasting ClosedShape to Shape
        ...
        return(0);
}
What is an incomplete type?
10. What is an incomplete type?
Incomplete types refers to pointers in which there is non availability of the implementation of the referenced location or it points to some location whose value is not available for modification. int *i=0x400 // i points to address 400 *i=0; //set the value of memory location pointed by i. Incomplete types are otherwise called uninitialized pointers.

Polymorphism

http://www.cplusplus.com/doc/tutorial/polymorphism/

http://www.cplusplus.com/doc/tutorial/typecasting/

Before getting any deeper into this chapter, you should have a proper understanding of pointers and class inheritance. If you are not really sure of the meaning of any of the following expressions, you should review the indicated sections:
Statement:
Explained in:
int A::b(int c) { }
a->b
class A: public B {};

Pointers to base class

One of the key features of class inheritance is that a pointer to a derived class is type-compatible with a pointer to its base class. Polymorphism is the art of taking advantage of this simple but powerful and versatile feature. The example about the rectangle and triangle classes can be rewritten using pointers taking this feature into account:
1

  2

  3

  4

  5

  6

  7

  8

  9

  10

  11

  12

  13

  14

  15

  16

  17

  18

  19

  20

  21

  22

  23

  24

  25

  26

  27

  28

  29

  30

  31

  32

  33

  34

  35
// pointers to base class
#include <iostream>
using namespace std;
 
class Polygon {
  protected:
    int width, height;
  public:
    void set_values (int a, int b)
      { width=a; height=b; }
};
 
class Rectangle: public Polygon {
  public:
    int area()
      { return width*height; }
};
 
class Triangle: public Polygon {
  public:
    int area()
      { return width*height/2; }
};
 
int main () {
  Rectangle rect;
  Triangle trgl;
  Polygon * ppoly1 = &rect;
  Polygon * ppoly2 = &trgl;
  ppoly1->set_values (4,5);
  ppoly2->set_values (4,5);
  cout << rect.area() << '\n';
  cout << trgl.area() << '\n';
  return 0;
}
20
10
Function main declares two pointers to Polygon (named ppoly1 and ppoly2). These are assigned the addresses of rect and trgl, respectively, which are objects of type Rectangle and Triangle. Such assignments are valid, since both Rectangle and Triangle are classes derived from Polygon. Dereferencing ppoly1 and ppoly2 (with *ppoly1 and *ppoly2) is valid and allows us to access the members of their pointed objects. For example, the following two statements would be equivalent in the previous example:
1

  2
ppoly1->set_values (4,5);
rect.set_values (4,5);
But because the type of ppoly1 and ppoly2 is pointer to Polygon (and not pointer to Rectangle nor pointer to Triangle), only the members inherited from Polygon can be accessed, and not those of the derived classes Rectangle and Triangle. That is why the program above accesses the area members of both objects using rect and trgl directly, instead of the pointers; the pointers to the base class cannot access the area members. Member area could have been accessed with the pointers to Polygon if area were a member of Polygon instead of a member of its derived classes, but the problem is that Rectangle and Triangle implement different versions of area, therefore there is not a single common version that could be implemented in the base class.

Virtual members

A virtual member is a member function that can be redefined in a derived class, while preserving its calling properties through references. The syntax for a function to become virtual is to precede its declaration with the virtual keyword:
1

  2

  3

  4

  5

  6

  7

  8

  9

  10

  11

  12

  13

  14

  15

  16

  17

  18

  19

  20

  21

  22

  23

  24

  25

  26

  27

  28

  29

  30

  31

  32

  33

  34

  35

  36

  37

  38

  39

  40

  41
// virtual members
#include <iostream>
using namespace std;
 
class Polygon {
  protected:
    int width, height;
  public:
    void set_values (int a, int b)
      { width=a; height=b; }
    virtual int area ()
      { return 0; }
};
 
class Rectangle: public Polygon {
  public:
    int area ()
      { return width * height; }
};
 
class Triangle: public Polygon {
  public:
    int area ()
      { return (width * height / 2); }
};
 
int main () {
  Rectangle rect;
  Triangle trgl;
  Polygon poly;
  Polygon * ppoly1 = &rect;
  Polygon * ppoly2 = &trgl;
  Polygon * ppoly3 = &poly;
  ppoly1->set_values (4,5);
  ppoly2->set_values (4,5);
  ppoly3->set_values (4,5);
  cout << ppoly1->area() << '\n';
  cout << ppoly2->area() << '\n';
  cout << ppoly3->area() << '\n';
  return 0;
}
20
10
0
In this example, all three classes (Polygon, Rectangle and Triangle) have the same members: width, height, and functions set_values and area. The member function area has been declared as virtual in the base class because it is later redefined in each of the derived classes. Non-virtual members can also be redefined in derived classes, but non-virtual members of derived classes cannot be accessed through a reference of the base class: i.e., if virtual is removed from the declaration of area in the example above, all three calls to area would return zero, because in all cases, the version of the base class would have been called instead. Therefore, essentially, what the virtual keyword does is to allow a member of a derived class with the same name as one in the base class to be appropriately called from a pointer, and more precisely when the type of the pointer is a pointer to the base class that is pointing to an object of the derived class, as in the above example. A class that declares or inherits a virtual function is called a polymorphic class. Note that despite of the virtuality of one of its members, Polygon was a regular class, of which even an object was instantiated (poly), with its own definition of member area that always returns 0.

Abstract base classes

Abstract base classes are something very similar to the Polygon class in the previous example. They are classes that can only be used as base classes, and thus are allowed to have virtual member functions without definition (known as pure virtual functions). The syntax is to replace their definition by =0 (and equal sign and a zero): An abstract base Polygon class could look like this:
1

  2

  3

  4

  5

  6

  7

  8

  9
// abstract class CPolygon
class Polygon {
  protected:
    int width, height;
  public:
    void set_values (int a, int b)
      { width=a; height=b; }
    virtual int area () =0;
};
Notice that area has no definition; this has been replaced by =0, which makes it a pure virtual function. Classes that contain at least one pure virtual function are known as abstract base classes. Abstract base classes cannot be used to instantiate objects. Therefore, this last abstract base class version of Polygon could not be used to declare objects like:
 
Polygon mypolygon;   // not working if Polygon is abstract base class 
But an abstract base class is not totally useless. It can be used to create pointers to it, and take advantage of all its polymorphic abilities. For example, the following pointer declarations would be valid:
1

  2
Polygon * ppoly1;
Polygon * ppoly2;
And can actually be dereferenced when pointing to objects of derived (non-abstract) classes. Here is the entire example:
1

  2

  3

  4

  5

  6

  7

  8

  9

  10

  11

  12

  13

  14

  15

  16

  17

  18

  19

  20

  21

  22

  23

  24

  25

  26

  27

  28

  29

  30

  31

  32

  33

  34

  35

  36
// abstract base class
#include <iostream>
using namespace std;
 
class Polygon {
  protected:
    int width, height;
  public:
    void set_values (int a, int b)
      { width=a; height=b; }
    virtual int area (void) =0;
};
 
class Rectangle: public Polygon {
  public:
    int area (void)
      { return (width * height); }
};
 
class Triangle: public Polygon {
  public:
    int area (void)
      { return (width * height / 2); }
};
 
int main () {
  Rectangle rect;
  Triangle trgl;
  Polygon * ppoly1 = &rect;
  Polygon * ppoly2 = &trgl;
  ppoly1->set_values (4,5);
  ppoly2->set_values (4,5);
  cout << ppoly1->area() << '\n';
  cout << ppoly2->area() << '\n';
  return 0;
}
20
10
In this example, objects of different but related types are referred to using a unique type of pointer (Polygon*) and the proper member function is called every time, just because they are virtual. This can be really useful in some circumstances. For example, it is even possible for a member of the abstract base class Polygon to use the special pointer this to access the proper virtual members, even though Polygon itself has no implementation for this function:
1

  2

  3

  4

  5

  6

  7

  8

  9

  10

  11

  12

  13

  14

  15

  16

  17

  18

  19

  20

  21

  22

  23

  24

  25

  26

  27

  28

  29

  30

  31

  32

  33

  34

  35

  36

  37

  38

  39
// pure virtual members can be called
// from the abstract base class
#include <iostream>
using namespace std;
 
class Polygon {
  protected:
    int width, height;
  public:
    void set_values (int a, int b)
      { width=a; height=b; }
    virtual int area() =0;
    void printarea()
      { cout << this->area() << '\n'; }
};
 
class Rectangle: public Polygon {
  public:
    int area (void)
      { return (width * height); }
};
 
class Triangle: public Polygon {
  public:
    int area (void)
      { return (width * height / 2); }
};
 
int main () {
  Rectangle rect;
  Triangle trgl;
  Polygon * ppoly1 = &rect;
  Polygon * ppoly2 = &trgl;
  ppoly1->set_values (4,5);
  ppoly2->set_values (4,5);
  ppoly1->printarea();
  ppoly2->printarea();
  return 0;
}
20
10
Virtual members and abstract classes grant C++ polymorphic characteristics, most useful for object-oriented projects. Of course, the examples above are very simple use cases, but these features can be applied to arrays of objects or dynamically allocated objects. Here is an example that combines some of the features in the latest chapters, such as dynamic memory, constructor initializers and polymorphism:
1

  2

  3

  4

  5

  6

  7

  8

  9

  10

  11

  12

  13

  14

  15

  16

  17

  18

  19

  20

  21

  22

  23

  24

  25

  26

  27

  28

  29

  30

  31

  32

  33

  34

  35

  36

  37
// dynamic allocation and polymorphism
#include <iostream>
using namespace std;
 
class Polygon {
  protected:
    int width, height;
  public:
    Polygon (int a, int b) : width(a), height(b) {}
    virtual int area (void) =0;
    void printarea()
      { cout << this->area() << '\n'; }
};
 
class Rectangle: public Polygon {
  public:
    Rectangle(int a,int b) : Polygon(a,b) {}
    int area()
      { return width*height; }
};
 
class Triangle: public Polygon {
  public:
    Triangle(int a,int b) : Polygon(a,b) {}
    int area()
      { return width*height/2; }
};
 
int main () {
  Polygon * ppoly1 = new Rectangle (4,5);
  Polygon * ppoly2 = new Triangle (4,5);
  ppoly1->printarea();
  ppoly2->printarea();
  delete ppoly1;
  delete ppoly2;
  return 0;
}
20
10
Notice that the ppoly pointers:
1

  2
Polygon * ppoly1 = new Rectangle (4,5);
Polygon * ppoly2 = new Triangle (4,5);
are declared being of type "pointer to Polygon", but the objects allocated have been declared having the derived class type directly (Rectangle and Triangle).

Type casting

C++ is a strong-typed language. Many conversions, specially those that imply a different interpretation of the value, require an explicit conversion, known in C++ as type-casting. There exist two main syntaxes for generic type-casting: functional and c-like:
1

  2

  3

  4
double x = 10.3;
int y;
y = int (x);    // functional notation
y = (int) x;    // c-like cast notation 
The functionality of these generic forms of type-casting is enough for most needs with fundamental data types. However, these operators can be applied indiscriminately on classes and pointers to classes, which can lead to code that -while being syntactically correct- can cause runtime errors. For example, the following code compiles without errors:
1

  2

  3

  4

  5

  6

  7

  8

  9

  10

  11

  12

  13

  14

  15

  16

  17

  18

  19

  20

  21

  22
// class type-casting
#include <iostream>
using namespace std;
 
class Dummy {
    double i,j;
};
 
class Addition {
    int x,y;
  public:
    Addition (int a, int b) { x=a; y=b; }
    int result() { return x+y;}
};
 
int main () {
  Dummy d;
  Addition * padd;
  padd = (Addition*) &d;
  cout << padd->result();
  return 0;
}
 
The program declares a pointer to Addition, but then it assigns to it a reference to an object of another unrelated type using explicit type-casting:
 
padd = (Addition*) &d;
Unrestricted explicit type-casting allows to convert any pointer into any other pointer type, independently of the types they point to. The subsequent call to member result will produce either a run-time error or some other unexpected results. In order to control these types of conversions between classes, we have four specific casting operators: dynamic_cast, reinterpret_cast, static_cast and const_cast. Their format is to follow the new type enclosed between angle-brackets (<>) and immediately after, the expression to be converted between parentheses. dynamic_cast <new_type> (expression) reinterpret_cast <new_type> (expression) static_cast <new_type> (expression) const_cast <new_type> (expression) The traditional type-casting equivalents to these expressions would be: (new_type) expression new_type (expression) but each one with its own special characteristics:

dynamic_cast

dynamic_cast can only be used with pointers and references to classes (or with void*). Its purpose is to ensure that the result of the type conversion points to a valid complete object of the destination pointer type. This naturally includes pointer upcast (converting from pointer-to-derived to pointer-to-base), in the same way as allowed as an implicit conversion. But dynamic_cast can also downcast (convert from pointer-to-base to pointer-to-derived) polymorphic classes (those with virtual members) if -and only if- the pointed object is a valid complete object of the target type. For example:
1

  2

  3

  4

  5

  6

  7

  8

  9

  10

  11

  12

  13

  14

  15

  16

  17

  18

  19

  20

  21

  22

  23
// dynamic_cast
#include <iostream>
#include <exception>
using namespace std;
 
class Base { virtual void dummy() {} };
class Derived: public Base { int a; };
 
int main () {
  try {
    Base * pba = new Derived;
    Base * pbb = new Base;
    Derived * pd;
 
    pd = dynamic_cast<Derived*>(pba);
    if (pd==0) cout << "Null pointer on first type-cast.\n";
 
    pd = dynamic_cast<Derived*>(pbb);
    if (pd==0) cout << "Null pointer on second type-cast.\n";
 
  } catch (exception& e) {cout << "Exception: " << e.what();}
  return 0;
}
Null pointer on second type-cast.
Below statement executes by compiler because pd is not pointing to 0 location means nowhere, because child memory not allocated at this point only parent memory is allocated and it is not the complete object, derive class pointer can pointer to location if derived class memory allocated which has parent memory block also,  that is why first statement “pd = dynamic_cast<Derived*>(pba); pd is complete object since it has memory location of complete child and which has base part inherited from parent too.
    pd = dynamic_cast<Derived*>(pbb);
    if (pd==0) cout << "Null pointer on second type-cast.\n";
Incomplete types refers to pointers in which there is non availability of the implementation of the referenced location or it points to some location whose value is not available for modification. int *i=0x400 // i points to address 400 *i=0; //set the value of memory location pointed by i. Incomplete types are otherwise called uninitialized pointers.
Compatibility note: This type of dynamic_cast requires Run-Time Type Information (RTTI) to keep track of dynamic types. Some compilers support this feature as an option which is disabled by default. This needs to be enabled for runtime type checking using dynamic_cast to work properly with these types.
The code above tries to perform two dynamic casts from pointer objects of type Base* (pba and pbb) to a pointer object of type Derived*, but only the first one is successful. Notice their respective initializations:
1

  2
Base * pba = new Derived;
Base * pbb = new Base;
Even though both are pointers of type Base*, pba actually points to an object of type Derived, while pbb points to an object of type Base. Therefore, when their respective type-casts are performed using dynamic_cast, pba is pointing to a full object of class Derived, whereas pbb is pointing to an object of class Base, which is an incomplete object of class CDerived. When dynamic_cast cannot cast a pointer because it is not a complete object of the required class -as in the second conversion in the previous example- it returns a null pointer to indicate the failure. If dynamic_cast is used to convert to a reference type and the conversion is not possible, an exception of type bad_cast is thrown instead. dynamic_cast can also perform the other implicit casts allowed on pointers: casting null pointers between pointers types (even between unrelated classes), and casting any pointer of any type to a void* pointer.

static_cast

static_cast can perform conversions between pointers to related classes, not only upcasts (from pointer-to-derived to pointer-to-base), but also downcasts (from pointer-to-base to pointer-to-derived). No checks are performed during runtime to guarantee that the object being converted is in fact a full object of the destination type. Therefore, it is up to the programmer to ensure that the conversion is safe. On the other side, it does not incur the overhead of the type-safety checks of dynamic_cast.
1

  2

  3

  4
class Base {};
class Derived: public Base {};
Base * a = new Base;
Derived * b = static_cast<Derived*>(a);
This would be valid code, although b would point to an incomplete object of the class and could lead to runtime errors if dereferenced. Therefore, static_cast is able to perform with pointers to classes not only the conversions allowed implicitly, but also their opposite conversions. static_cast is also able to perform all conversions allowed implicitly (not only those with pointers to classes), and is also able to perform the opposite of these. It can:
  • Convert from void* to any pointer type. In this case, it guarantees that if the void* value was obtained by converting from that same pointer type, the resulting pointer value is the same.
  • Convert integers, floating-point values and enum types to enum types.</i>
Additionally, static_cast can also perform the following:
  • Explicitly call a single-argument constructor or a conversion operator.
  • Convert to rvalue references.
  • Convert enum class values into integers or floating-point values.
  • Convert any type to void, evaluating and discarding the value.

reinterpret_cast

reinterpret_cast converts any pointer type to any other pointer type, even of unrelated classes. The operation result is a simple binary copy of the value from one pointer to the other. All pointer conversions are allowed: neither the content pointed nor the pointer type itself is checked. It can also cast pointers to or from integer types. The format in which this integer value represents a pointer is platform-specific. The only guarantee is that a pointer cast to an integer type large enough to fully contain it (such as intptr_t), is guaranteed to be able to be cast back to a valid pointer. The conversions that can be performed by reinterpret_cast but not by static_cast are low-level operations based on reinterpreting the binary representations of the types, which on most cases results in code which is system-specific, and thus non-portable. For example:
1

  2

  3

  4
class A { /* ... */ };
class B { /* ... */ };
A * a = new A;
B * b = reinterpret_cast<B*>(a);
This code compiles, although it does not make much sense, since now b points to an object of a totally unrelated and likely incompatible class. Dereferencing b is unsafe.

const_cast

This type of casting manipulates the constness of the object pointed by a pointed, either to be set or to be removed. For example, in order to pass a const pointer to a function that expects a non-const argument:
1

  2

  3

  4

  5

  6

  7

  8

  9

  10

  11

  12

  13

  14
// const_cast
#include <iostream>
using namespace std;
 
void print (char * str)
{
  cout << str << '\n';
}
 
int main () {
  const char * c = "sample text";
  print ( const_cast<char *> (c) );
  return 0;
}
sample text
The example above is guaranteed to work because function print does not write to the pointed object. Note though, that removing the constness of a pointed object to actually write to it causes undefined behavior.

typeid

typeid allows to check the type of an expression: typeid (expression) This operator returns a reference to a constant object of type type_info that is defined in the standard header <typeinfo>. A value returned by typeid can be compared with another value returned by typeid using operators == and != or can serve to obtain a null-terminated character sequence representing the data type or class name by using its name() member.
1

  2

  3

  4

  5

  6

  7

  8

  9

  10

  11

  12

  13

  14

  15

  16
// typeid
#include <iostream>
#include <typeinfo>
using namespace std;
 
int main () {
  int * a,b;
  a=0; b=0;
  if (typeid(a) != typeid(b))
  {
    cout << "a and b are of different types:\n";
    cout << "a is: " << typeid(a).name() << '\n';
    cout << "b is: " << typeid(b).name() << '\n';
  }
  return 0;
}
a and b are of different types:
a is: int *
b is: int  
When typeid is applied to classes, typeid uses the RTTI to keep track of the type of dynamic objects. When typeid is applied to an expression whose type is a polymorphic class, the result is the type of the most derived complete object:
1

  2

  3

  4

  5

  6

  7

  8

  9

  10

  11

  12

  13

  14

  15

  16

  17

  18

  19

  20
// typeid, polymorphic class
#include <iostream>
#include <typeinfo>
#include <exception>
using namespace std;
 
class Base { virtual void f(){} };
class Derived : public Base {};
 
int main () {
  try {
    Base* a = new Base;
    Base* b = new Derived;
    cout << "a is: " << typeid(a).name() << '\n';
    cout << "b is: " << typeid(b).name() << '\n';
    cout << "*a is: " << typeid(*a).name() << '\n';
    cout << "*b is: " << typeid(*b).name() << '\n';
  } catch (exception& e) { cout << "Exception: " << e.what() << '\n'; }
  return 0;
}
a is: class Base *
b is: class Base *
*a is: class Base
*b is: class Derived
Note: The string returned by member name of type_info depends on the specific implementation of your compiler and library. It is not necessarily a simple string with its typical type name, like in the compiler used to produce this output. Notice how the type that typeid considers for pointers is the pointer type itself (both a and b are of type class Base *). However, when typeid is applied to objects (like *a and *b) typeid yields their dynamic type (i.e. the type of their most derived complete object). If the type typeid evaluates is a pointer preceded by the dereference operator (*), and this pointer has a null value, typeid throws a bad_typeid exception.
class A{
protected:
       int a;
       int b;
public:
        void setvalue_A(int x, int y)
       {
                     cout << "Before assigining value default value a:" << a << "value of b:" << b<<"\n";
                     cin>>a;
              a=x;
              b=y;
                     cout << "Inside class A "<<"value of a:" << a << "value of b:" << b<<"\n";
                     cin>>a;
       }
};
class B:public A{
protected:
       int m;
       int n;
public:
        void setvalue_B(int x, int y)
       {
              m=x;
              n=y;
              a=m;
              b=n;
              cout << "Class B object"<<"value of m:m" << m << "value of n:" << n<<"\n";
              cin>>m;
              cout << "Class A object member"<<"value of :a" << a << "value of b:" << b<<"\n";
              cin>>m;
              cin>>m;
       }
};
int main( )
{
       A a1;
       B b;
       b.setvalue_A(4,5);
       b.setvalue_B(1,2);
      
   return 0;
}
Function Call Binding using Base class Pointer
But when we use a Base class's pointer or reference to hold Derived class's object, then Function call Binding gives some unexpected results.
class Base
{
 public:
 void show()
 {
  cout << "Base class";
 }
};
class Derived:public Base
{
 public:
 void show()
 {
  cout << "Derived Class";
 }
}
int mian()
{
 Base* b;       //Base class pointer
 Derived d;     //Derived class object
 b = &d;
 b->show();     //Early Binding Ocuurs
}
Output : Base class
In the above example, although, the object is of Derived class, still Base class's method is called. This happens due to Early Binding.
Compiler on seeing Base class's pointer, set call to Base class's show() function, without knowing the actual object type.

Virtual Functions

Virtual Function is a function in base class, which is overrided in the derived class, and which tells the compiler to perform Late Binding on this function.
Virtual Keyword is used to make a member function of the base class Virtual.


Late Binding

In Late Binding function call is resolved at runtime. Hence, now compiler determines the type of object at runtime, and then binds the function call. Late Binding is also called Dynamic Binding or Runtime Binding.


Problem without Virtual Keyword

class Base
{
 public:
 void show()
 {
  cout << "Base class";
 }
};
class Derived:public Base
{
 public:
 void show()
 {
  cout << "Derived Class";
 }
}
 
int main()
{
 Base* b;       //Base class pointer
 Derived d;     //Derived class object
 b = &d;
 b->show();     //Early Binding Ocuurs
}
Output : Base class
When we use Base class's pointer to hold Derived class's object, base class pointer or reference will always call the base version of the function


Using Virtual Keyword

We can make base class's methods virtual by using virtual keyword while declaring them. Virtual keyword will lead to Late Binding of that method.
class Base
{
 public:
 virtual void show()
 {
  cout << "Base class";
 }
};
class Derived:public Base
{
 public:
 void show()
 {
  cout << "Derived Class";
 }
}
 
int main()
{
 Base* b;       //Base class pointer
 Derived d;     //Derived class object
 b = &d;
 b->show();     //Late Binding Ocuurs
}
Output : Derived class
On using Virtual keyword with Base class's function, Late Binding takes place and the derived version of function will be called, because base class pointer pointes to Derived class object.


Mechanism of Late Binding

Description: mechanism of Late binding in C++
To accomplich late binding, Compiler creates VTABLEs, for each class with virtual function. The address of virtual functions is inserted into these tables. Whenever an object of such class is created the compiler secretly inserts a pointer called vpointer, pointing to VTABLE for that object. Hence when function is called, compiler is able to resovle the call by binding the correct function using the vpointer.


Important Points to Remember

1.    Only the Base class Method's declaration needs the Virtual Keyword, not the definition.
2.    If a function is declared as virtual in the base class, it will be virtual in all its derived classes.
3.    The address of the virtual Function is placed in the VTABLE and the copiler uses VPTR(vpointer) to point to the Virtual Function.

http://www.codeproject.com/Articles/602141/Polymorphism-in-NET

Polymorphism in .NET

Introduction

In this post, you will learn the following topics:
  1. Polymorphism
  2. Static or compile time polymorphism
    • Method overloading
  3. Dynamic or runtime polymorphism
    • Method overriding
  4. Virtual keyword and virtual method
  5. Difference between method overriding and method hiding
  6. Sealed method

What is Polymorphism?

Polymorphism means one name many forms. Polymorphism means one object behaving as multiple forms. One function behaves in different forms. In other words, "Many forms of a single object is called Polymorphism."

Real World Example of Polymorphism

Example 1

  • A Teacher behaves with student.
  • A Teacher behaves with his/her seniors.
Here teacher is an object but the attitude is different in different situations.

Example 2

  • Person behaves as a SON in house, at the same time that person behaves like an EMPLOYEE in the office.

Example 3

Your mobile phone, one name but many forms:
  • As phone
  • As camera
  • As mp3 player
  • As radio
With polymorphism, the same method or property can perform different actions depending on the run-time type of the instance that invokes it. There are two types of polymorphism:
  1. Static or compile time polymorphism
  2. Dynamic or runtime polymorphism
Description: http://www.codeproject.com/KB/dotnet/602141/image001.gif

Static or Compile Time Polymorphism

In static polymorphism, the decision is made at compile time.
  • Which method is to be called is decided at compile-time only.
  • Method overloading is an example of this.
  • Compile time polymorphism is method overloading, where the compiler knows which overloaded method it is going to call.
Method overloading is a concept where a class can have more than one method with the same name and different parameters. Compiler checks the type and number of parameters passed on to the method and decides which method to call at compile time and it will give an error if there are no methods that match the method signature of the method that is called at compile time.

Example

Description: http://www.codeproject.com/images/minus.gifCollapse | Copy Code
namespace MethodOverloadingByManishAgrahari
{
    class Program
    {
        public class TestOverloading
        {
 
            public void Add(string a1, string a2)
            {
                Console.WriteLine("Adding Two String :" + a1 + a2);
            }
 
            public void Add(int a1, int a2)
            {
                Console.WriteLine("Adding Two Integer :" +  a1 + a2);
            }
 
        }
 
        static void Main(string[] args)
        {
            TestOverloading obj = new TestOverloading();
 
            obj.Add("Manish " , "Agrahari");
 
            obj.Add(5, 10);
 
            Console.ReadLine();
        }
    }
}
Description: http://www.codeproject.com/KB/dotnet/602141/image002.gif

Dynamic or Runtime Polymorphism

Run-time polymorphism is achieved by method overriding. Method overriding allows us to have methods in the base and derived classes with the same name and the same parameters. By runtime polymorphism, we can point to any derived class from the object of the base class at runtime that shows the ability of runtime binding. Through the reference variable of a base class, the determination of the method to be called is based on the object being referred to by reference variable. Compiler would not be aware whether the method is available for overriding the functionality or not. So compiler would not give any error at compile time. At runtime, it will be decided which method to call and if there is no method at runtime, it will give an error. See the following example:
Description: http://www.codeproject.com/images/minus.gifCollapse | Copy Code
namespace PolymorphismByManishAgrahari
{
    class Program
    {
        public class Base
        {
 
            public virtual void Show()
            {
                Console.WriteLine("Show From Base Class.");
            }
        }
 
        public class Derived : Base
        {
            public override void Show()
            {
                Console.WriteLine("Show From Derived Class.");
            }
        }
        static void Main(string[] args)
        {
            Base objBase;
            objBase = new Base();
            objBase.Show();//    Output ----> Show From Base Class.
 
            objBase = new Derived();
            objBase.Show();//Output--> Show From Derived Class.
 
            Console.ReadLine();
        }
    }
} 
Compiler demands virtual Show() method and it compiles successfully. The right version of Show() method cannot be determined until run-time since only at that time Base objBase is initialized as Derived.

Virtual Keyword

According to MSDN, “The virtual keyword is used to modify a method, property, indexer or event declaration, and allow it to be overridden in a derived class.”

Virtual Method

Virtual method is a method whose behavior can be overridden in derived class. Virtual method allows declare a method in base class that can be redefined in each derived class. When a virtual method is invoked, the run-time type of the object is checked for an overriding member. The overriding member in the most derived class is called, which might be the original member, if no derived class has overridden the member.
  • By default, methods are non-virtual. You cannot override a non-virtual method.
  • You cannot use the virtual modifier with the static, abstract, private or override modifiers.
  • Virtual properties behave like abstract methods, except for the differences in declaration and invocation syntax.
  • It is an error to use the virtual modifier on a static property.
  • A virtual inherited property can be overridden in a derived class by including a property declaration that uses the override modifier.
Virtual method solves the following problem: In OOP, when a derived class inherits from a base class, an object of the derived class may be referred to (or cast) as either being the base class type or the derived class type. If there are base class methods overridden by the derived class, the method call behavior is ambiguous. In C#, polymorphism is explicit - you must have a virtual (or abstract) modifier on the base class method (member) and an override on the derived class method, which you probably already know. If you don't put a modifier on a base class method, polymorphism can't ever happen. If you then add a non-modified method to the derived class with the same signature as the non-modified base class method, the compiler will generate a Warning message. See the following example:
Description: http://www.codeproject.com/images/minus.gifCollapse | Copy Code
namespace PolymorphismByManishAgrahari
{
    class Program
    {
        public class Base
        {
 
            public void Show()
            {
                Console.WriteLine("Show From Base Class.");
            }
        }
 
        public class Derived : Base
        {
            //Following line will Give an Warning
            /*
             'PolymorphismByManishAgrahari.Program.Derived.Show()'
  hides  inherited member
             'PolymorphismByManishAgrahari.Program.Base.Show()'.
              Use the new keyword if hiding was intended.
            */
            public void Show()
            {
                Console.WriteLine("Show From Derived Class.");
            }
        }
        static void Main(string[] args)
        {
            Base objBase = new Base();
            objBase.Show();//    Output ----> Show From Base Class.
 
            Derived objDerived = new Derived();
            objDerived.Show();//Output--> Show From Derived Class.
 
 
            Base objBaseRefToDerived = new Derived();
            objBaseRefToDerived.Show();//Output--> Show From Base Class.
 
            Console.ReadLine();
        }
    }
}
It means that you are hiding (re-defining) the base class method. In other languages, take Java for instance, you have what is called "implicit" polymorphism where just putting the method in the derived class with the same signature as a base class method will enable polymorphism. In Java, all methods of a class are virtual by default unless the developer decides to use the final keyword thus preventing subclasses from overriding that method. In contrast, C# adopts the strategy used by C++ where the developer has to use the virtual keyword for subclasses to override the method. Thus all methods in C# are non virtual by default. The C# approach is more explicit for the purpose of making the code safer in versioning scenarios, i.e., you build your code based on a 3rd party library and use meaningful, but common, method names. The 3rd party library upgrades, using the same common method name. With implicit polymorphism the code would break, but with C#, you would receive a compiler warning so you can double check to see if polymorphism was something you wanted to do.

Difference between Method Overriding and Method Hiding

Method overriding allows a subclass to provide a specific implementation of a method that is already provided by base class. The implementation in the subclass overrides (replaces) the implementation in the base class. The important thing to remember about overriding is that the method that is doing the overriding is related to the method in the base class. When a virtual method is called on a reference, the actual type of the object to which the reference refers is used to determine which method implementation should be used. When a method of a base class is overridden in a derived class (subclass), the version defined in the derived class is used. This is so even should the calling application be unaware that the object is an instance of the derived class.
Description: http://www.codeproject.com/images/minus.gifCollapse | Copy Code
namespace PolymorphismByManishAgrahari
{
    class Program
    {
        public class Base
        {
 
            public virtual void Show()
            {
                Console.WriteLine("Show From Base Class.");
            }
        }
 
        public class Derived : Base
        {
//the keyword "override" change the base class method.
            public override void Show()
            {
                Console.WriteLine("Show From Derived Class.");
            }
        }
        static void Main(string[] args)
        {
            Base objBaseRefToDerived  = new Derived();
            objBaseRefToDerived .Show();//Output--> Show From Derived Class.
 
            Console.ReadLine();
        }
    }
}
Output--> Show From Derived Class Method hiding does not have a relationship between the methods in the base class and derived class. The method in the derived class hides the method in the base class.
Description: http://www.codeproject.com/images/minus.gifCollapse | Copy Code
namespace PolymorphismByManishAgrahari
{
    class Program
    {
        public class Base
        {
 
            public virtual void Show()
            {
                Console.WriteLine("Show From Base Class.");
            }
        }
 
        public class Derived : Base
        {
 
            public new void Show()
            {
                Console.WriteLine("Show From Derived Class.");
            }
        }
        static void Main(string[] args)
        {
            Base objBaseRefToDerived  = new Derived();
            objBaseRefToDerived .Show();//Output--> Show From Base Class.
 
            Console.ReadLine();
        }
    }
}
Output is:? Show From Base Class. In the preceding example, Derived.Show will be called; because, it overrides Base.Show. The C# language specification states that "You cannot override a non-virtual method." See the following example:
Description: http://www.codeproject.com/images/minus.gifCollapse | Copy Code
namespace PolymorphismByManishAgrahari
{
    class Program
    {
        public class Base
        {
 
            public void Show()
            {
                Console.WriteLine("This is Base Class.");
            }
        }
 
        public class Derived : Base
        {
            //Following Line will give error.
            /*
             Error:- 'PolymorphismByManishAgrahari.Program.Derived.Show()'
cannot override inherited member  'PolymorphismByManishAgrahari.Program.Base.Show()'
             * because it is not marked virtual, abstract, or override
             */
            public override void Show()
            {
 
                Console.WriteLine("This is Derived Class.");
            }
        }
        static void Main(string[] args)
        {
            Base objBase = new Base();
            objBase.Show();//    Output ----> This is Base Class.
 
            Derived objDerived = new Derived();
            objDerived.Show();//Output--> This is Derived Class.
 
            Base objBaseRefToDerived = new Derived();
            objBaseRefToDerived.Show();//Output--> This is Base Class.
 
            Console.ReadLine();
        }
    }
}
Error: 'PolymorphismByManishAgrahari.Program.Derived.Show()' cannot override inherited member 'PolymorphismByManishAgrahari.Program.Base.Show()' because it is not marked virtual, abstract, or override.

Sealed Keyword

Sealed keyword can be used to stop method overriding in a derived classes. By default, all methods are sealed, which means you can't override them, so that "sealed" keyword is redundant in this case and compiler will show you an error when you'll try to make sealed already sealed method. But if your method was marked as virtual in a base class, by overriding and marking this method with "sealed" will prevent method overriding in derived classes. See the following example:
Description: http://www.codeproject.com/images/minus.gifCollapse | Copy Code
namespace PolymorphismByManishAgrahari
{
    class Program
    {
        public class Base
        {
 
public sealed void Show()//This Line will give an error - "cannot
{                      //be sealed because it is not an override"
 
                Console.WriteLine("This is Base Class.");
            }
        }
 
        public class Derived : Base
        {
            public void Show()
            {
 
                Console.WriteLine("This is Derived Class.");
            }
        }
        static void Main(string[] args)
        {
            Base objBaseReference = new Derived();
            objBaseReference.Show();// Output ---------> This is Base Class.
 
            Console.ReadLine();
        }
    }
}
Error: 'PolymorphismByManishAgrahari.Program.Base.Show()' cannot be sealed because it is not an override. To remove error from the above program, use the following:
Description: http://www.codeproject.com/images/minus.gifCollapse | Copy Code
namespace PolymorphismByManishAgrahari
{
    class Program
    {
        public class Base
        {
 
            public virtual void Show()
            {
                Console.WriteLine("This is Base Class.");
            }
        }
 
        public class Derived : Base
        {
            public override sealed void Show()
            {
 
                Console.WriteLine("This is Derived Class.");
            }
        }
 
        static void Main(string[] args)
        {
            Base objBaseReference = new Derived();
            objBaseReference.Show();// Output ---> This is Derived Class.
 
            Console.ReadLine();
        }
    }
}
Output ---> This is Derived Class.

Summary

  1. It is not compulsory to mark the derived/child class function with override keyword while base/parent class contains a virtual method.
  2. Virtual methods allow subclasses to provide their own implementation of that method using the override keyword.
  3. Virtual methods can't be declared as private.
  4. You are not required to declare a method as virtual. But, if you don't, and you derive from the class, and your derived class has a method by the same name and signature, you'll get a warning that you are hiding a parent's method.
  5. A virtual property or method has an implementation in the base class, and can be overridden in the derived classes.
  6. We will get a warning if we won't use Virtual/New keyword.

  7. Instead of Virtual, we can use New keyword.
The word polymorphism means having many forms. In object-oriented programming paradigm, polymorphism is often expressed as 'one interface, multiple functions'.
Polymorphism can be static or dynamic. In static polymorphism the response to a function is determined at the compile time. In dynamic polymorphism , it is decided at run-time.

Static Polymorphism

The mechanism of linking a function with an object during compile time is called early binding. It is also called static binding. C# provides two techniques to implement static polymorphism. These are:
·         Function overloading
·         Operator overloading
We will discuss function overloading in the next section and operator overloading will be dealt with in next chapter.

Function Overloading

You can have multiple definitions for the same function name in the same scope. The definition of the function must differ from each other by the types and/or the number of arguments in the argument list. You cannot overload function declarations that differ only by return type.
Following is the example where same function print() is being used to print different data types:
using System;
namespace PolymorphismApplication
{
   class Printdata
   {
      void print(int i)
      {
         Console.WriteLine("Printing int: {0}", i );
      }
 
      void print(double f)
      {
         Console.WriteLine("Printing float: {0}" , f);
      }
 
      void print(string s)
      {
         Console.WriteLine("Printing string: {0}", s);
      }
      static void Main(string[] args)
      {
         Printdata p = new Printdata();
         // Call print to print integer
         p.print(5);
         // Call print to print float
         p.print(500.263);
         // Call print to print string
         p.print("Hello C++");
         Console.ReadKey();
      }
   }
}
When the above code is compiled and executed, it produces the following result:
Printing int: 5
Printing float: 500.263
Printing string: Hello C++

Dynamic Polymorphism

C# allows you to create abstract classes that are used to provide partial class implementation of an interface. Implementation is completed when a derived class inherits from it. Abstract classes contain abstract methods, which are implemented by the derived class. The derived classes have more specialized functionality.
Please note the following rules about abstract classes:
·         You cannot create an instance of an abstract class
·         You cannot declare an abstract method outside an abstract class
·         When a class is declared sealed, it cannot be inherited, abstract classes cannot be declared sealed.
The following program demonstrates an abstract class:
using System;
namespace PolymorphismApplication
{
   abstract class Shape
   {
      public abstract int area();
   }
   class Rectangle:  Shape
   {
      private int length;
      private int width;
      public Rectangle( int a=0, int b=0)
      {
         length = a;
         width = b;
      }
      public override int area ()
      { 
         Console.WriteLine("Rectangle class area :");
         return (width * length); 
      }
   }
 
   class RectangleTester
   {
      static void Main(string[] args)
      {
         Rectangle r = new Rectangle(10, 7);
         double a = r.area();
         Console.WriteLine("Area: {0}",a);
         Console.ReadKey();
      }
   }
}
When the above code is compiled and executed, it produces the following result:
Rectangle class area :
Area: 70
When you have a function defined in a class that you want to be implemented in an inherited class(es), you use virtual functions. The virtual functions could be implemented differently in different inherited class and the call to these functions will be decided at runtime.
Dynamic polymorphism is implemented by abstract classes and virtual functions.
The following program demonstrates this:
using System;
namespace PolymorphismApplication
{
   class Shape 
   {
      protected int width, height;
      public Shape( int a=0, int b=0)
      {
         width = a;
         height = b;
      }
      public virtual int area()
      {
         Console.WriteLine("Parent class area :");
         return 0;
      }
   }
   class Rectangle: Shape
   {
      public Rectangle( int a=0, int b=0): base(a, b)
      {
 
      }
      public override int area ()
      {
         Console.WriteLine("Rectangle class area :");
         return (width * height); 
      }
   }
   class Triangle: Shape
   {
      public Triangle(int a = 0, int b = 0): base(a, b)
      {
      
      }
      public override int area()
      {
         Console.WriteLine("Triangle class area :");
         return (width * height / 2); 
      }
   }
   class Caller
   {
      public void CallArea(Shape sh)
      {
         int a;
         a = sh.area();
         Console.WriteLine("Area: {0}", a);
      }
   }  
   class Tester
   {
      
      static void Main(string[] args)
      {
         Caller c = new Caller();
         Rectangle r = new Rectangle(10, 7);
         Triangle t = new Triangle(10, 5);
         c.CallArea(r);
         c.CallArea(t);
         Console.ReadKey();
      }
   }
}
When the above code is compiled and executed, it produces the following result:
Rectangle class area:
Area: 70
Triangle class area:
Area: 25
You can redefine or overload most of the built-in operators available in C#. Thus a programmer can use operators with user-defined types as well. Overloaded operators are functions with special names the keyword operator followed by the symbol for the operator being defined. Like any other function, an overloaded operator has a return type and a parameter list.
For example, look at the following function:
public static Box operator+ (Box b, Box c)
{
   Box box = new Box();
   box.length = b.length + c.length;
   box.breadth = b.breadth + c.breadth;
   box.height = b.height + c.height;
   return box;
}
The above function implements the addition operator (+) for a user-defined class Box. It adds the attributes of two Box objects and returns the resultant Box object.

Overloading Is A Type Of Dynamic Polymorphis

Polymorphism is the occurrence of something in different forms where 'poly' means many and ‘morphism’ means form.
It is an ability of an object to take different forms based on the situation.
Creating a method in the derived class with the same signature as a method in base class is called as method overriding.
Let’s see if overriding can bring run time polymorphism.

Background

Let me start my story first.
  • Bird can fly but cannot run.
  • Penguin is a bird which cannot fly but can run.
Requirements are to show:
  • What Bird does and does not do?
  • What penguin does and does not do?
  • What Bird and Penguin can do?

Using the Code

Based on the above story, let’s build our requirement.
Let me introduce you to three key words.
  • Virtual: The virtual key word is used to modify a method and allow it to be overridden in derived class, i.e., it says that I am the first version and the next version will get derived in the derived class.
  • Override: The override key word is use to declare new version of method that is derived in the base class.
  • New: The new keyword is used to hide the inherited method declared in the base class and modify it with new modifier, i.e. it hid the base class method and says that it is the complete new implementation of the method.
So you need to build the following structure:
Description: http://www.codeproject.com/KB/cs/581458/Untitled.png

Bird Base Class

Description: http://www.codeproject.com/images/minus.gifCollapse | Copy Code
/// <summary>
///Base class
/// </summary>
public class Bird
{
    string Name { get; set; }
    public Bird()
    {
        Name = "Bird ";
    }
    public virtual void Fly()
    {
        Console.WriteLine(Name+"I can fly.");
    }
    public virtual void Run()
    {
        Console.WriteLine(Name+"I can not run.");
    }
}

Penguin Derived Class

Description: http://www.codeproject.com/images/minus.gifCollapse | Copy Code
/// <summary>
/// derived class
/// </summary>
public class Penguin:Bird
{
    string Name { get; set; }
    public Penguin()
    {
        Name = "Penguin ";
    }
    public new void Fly()
    {
        Console.WriteLine(Name + "I can not fly");
    }
    public override void Run()
    {
        Console.WriteLine(Name+"I can Run");
    }
} 
We want what Bird and Penguin can do?
Description: http://www.codeproject.com/images/minus.gifCollapse | Copy Code
  Bird bird1 = new Penguin(); 
Let's look at the above code. We assign the penguin class to the variable of the bird class. Is it not the same as type casting?
Description: http://www.codeproject.com/images/minus.gifCollapse | Copy Code
bird1.Run();
bird1.Fly(); 
Look at the above call as both the methods are virtual and object is of type cast from derived to base class object.
So the compiler will find the override method in the derived class. As virtual says that next version of same method is defined in the derived class and override says that it is the next version of the same method declared as virtual in base class. Compiler will reference the derived class Run() method instead of base class Run() method. But for base class fly() method, we have a complete new implementation for derived class fly() method denoted by the keyword New and compiler did not find any override implementation of it so compiler reference to base class fly() method.
Fine enough that we want.
Description: http://www.codeproject.com/images/minus.gifCollapse | Copy Code
static void Main(string[] args)
{
    //using bird class
    Console.WriteLine("Creating bird object........");
    Bird bird = new Bird();
    bird.Run();
    bird.Fly();
    
    //using penguin class
    Console.WriteLine("Creating penguin object........");
    Penguin penguin = new Penguin();
    penguin.Run();
    penguin.Fly();
    
    //Assign penguin to bird
    Console.WriteLine("Creating penguin object and assign to bird........");
    Bird bird1 = new Penguin();
    bird1.Run();
    bird1.Fly();
    Console.Read();    
} 
We have the same method name in base and derived class and we are using object of base class having the same method name Run() with different implementation during run time call as dynamic polymorphism.
The original aim of this article was to explain Up-casting and Down-casting. Having started writing the article, I was struggling to find an ideal way to describe these two concepts. Having thought further about it, one way I found was to introduce the concept of polymorphism to help explain up and down-casting. This has expanded the article further and when you have finished reading it, you should hopefully understand the three concepts better.

Polymorphism

Polymorphism is a powerful aspect of object oriented programming. According to many searches on the Internet to find a definitive meaning, I have found two that seem to explain it quite nicely, these are "Having many forms" and "Having multiple forms".
Consider the following. Ask yourself, what is a circle? Most would say a circle is a shape. A square, rectangle and a triangle are also shapes. So, what we are saying is a shape can take on many forms or has multiple forms. So how do we implement this concept in C#?
First we need to design our base class, this will be called Shape. Our shape class will implement a constructor that will accept an X and Y co-ordinate and a method that will draw our shape. Below is the code for our shape class.
public class Shape
{
    protected int m_xpos;
    protected int m_ypos;
    public Shape()
    {
    }
    public Shape(int x, int y)
    {
        m_xpos = x;
        m_ypos = y;
    }
    public virtual void Draw()
    {
        Console.WriteLine("Drawing a SHAPE at {0},{1}", m_xpos, m_ypos);
    }
}
We now need to make our Draw method behave polymorphically. To do this, we declare our method with the keyword virtual in our base class. When we derive a class from shape we are able to implement a specific version of Draw by overriding the base class implementation of Draw. To do this, we use the keyword override when declaring our Draw method in our derived classes. 

What we will now do is implement two derived classes from our shape base class. We will implement Circle and Square. This will show how we override our base class Draw method.  Circle and Square derived classes

One thing to note about the base class is the fact that I have used protected variables for the X and Y co-ordinates. Ideally you would use public properties and declare m_xpos and m_ypos as private.
Here are our two derived classes.
public class Square : Shape
{
    public Square()
    {
    }
    public Square(int x, int y) : base(x, y)
    {
    }
    public override void Draw()
    {
        Console.WriteLine("Drawing a SQUARE at {0},{1}", m_xpos, m_ypos);
    }
}
And finally Circle...  
public class Circle : Shape
{
    public Circle()
    {
    }
    public Circle(int x, int y) : base(x, y)
    {
    }
    public override void Draw()
    {
        Console.WriteLine("Drawing a CIRCLE at {0},{1}", m_xpos, m_ypos);
    }
Notice, the highlighted code blocks. We have overridden the base class implementation of Draw in each of our derived classes. Basically override tells the compiler that we are intentionally overriding the behaviour of Draw.
We will now test the classes we have written, by putting together a simple piece of code that will create an instance of Shape, Circle and Square and call the Draw methods for each type.
class Program
{
    static void Main(string[] args)
    {
        Shape sh = new Shape(100, 100);
        sh.Draw();
        Square sq = new Square(200, 200);
        sq.Draw();
        Circle ci = new Circle(300, 300);
        ci.Draw();
    }
}  The output generated by the test code is:
Drawing a SHAPE at 100,100
Drawing a SQUARE at 200,200
Drawing a CIRCLE at 300,300
So what's happened that's polymorphic? Well, at this point absolutely nothing! Consider the code below.
class Program
{
    static void Main(string[] args)
    {
        Shape[] shapes = new Shape[3];
        shapes[0] = new Shape(100, 100);
        shapes[1] = new Square(200, 200);
        shapes[2] = new Circle(300, 300);
        foreach (Shape shape in shapes)
        shape.Draw();
    }
}
What we have done is to create an array of the type Shape. Because Square and Circle are derived from Shape, we are able to put them in our array. What we are then doing is looping through all the elements of our array and calling Draw for each of our types. Because we have overridden the Draw method in each of our derived classes the output of our code is:
Drawing a SHAPE at 100,100
Drawing a SQUARE at 200,200
Drawing a CIRCLE at 300,300
If we did not override Draw in one of our derived classes, the base class implementation of Draw would be called. For example, if we declared Draw in our Circle class as follows:
public void Draw()
{
    Console.WriteLine("Drawing a CIRCLE at {0},{1}", m_xpos, m_ypos);
}
Our output would be:
Drawing a SHAPE at 100,100
Drawing a SQUARE at 200,200
Drawing a SHAPE at 300,300
By declaring the method as shown above, we will receive a compiler warning as follows:
Polymorphism.Circle.Draw() : Hides inherited member.
  
Polymorphism.Shape.Draw() :To make the current member override that implementation, add the override keyword. Otherwise add the new keyword.
If we do not want to override the base class method, we need to use the new keyword when declaring our method, for example:
public new void Draw()
{
    Console.WriteLine("Drawing a CIRCLE at {0},{1}", m_xpos, m_ypos);
}
This will remove the compiler warning. Basically we are telling the compiler that we are not overriding the base class implementation.
So what have we achieved with polymorphism? What we have been able to do is create an array of shapes and add a specific shape to each element of the array. When drawing each shape, we have not concerned ourselves with the fact that the shape could be a circle or a square. We have simply said, "here is an array of shapes, please draw them!"  It is the responsibility of the compiler to discover the real type and to ensure that the correct implementation is called.   Up-casting 
Now we come on to one of the original goals of the article. With the simple example above of polymorphism, you should be able to quickly understand what up-casting is, in fact we have already used up-casting in our example.
The diagram below is a UML diagram for our polymorphism example. Description: http://www.c-sharpcorner.com/UploadFile/pcurnow/polymorphcasting06222007131659PM/Images/Img1.jpg Figure 1: UML Diagram For Shape. 
Consider the following code:
Shape s = new Circle(100, 100);
We have cast Circle to the type Shape. This is perfectly legal code (as we saw in the Polymorphism example). This is possible, because Circle has been derived from Shape and you expect all methods and properties of Shape to exist in Circle. Executing the Draw method by doing s.Draw() gives the following output:
Drawing a CIRCLE at 100,100
If we had declared the Draw method in Circle as follows, public new void Draw() the output would have been:
Drawing a SHAPE at 100,100
As we have already mentioned, marking the method with new, tells the compiler that we are not overriding the base class implementation of the method.
So why is this called up-casting? Consider the diagram above. From Circle, we are moving up the object hierarchy to the type Shape, so we are casting our object "upwards" to its parent type.
Up-casting is implicit and is safe. What do we mean by safe? Well, we can happily cast Circle toShape and expect all the properties and methods of Shape to be available.  Down-casting 
The flip side of the coin to up-casting is ...yes you guessed it, down-casting. Down-casting takes a little more understanding and you have to be very careful when down-casting types.
To help us better understand down-casting, we are going to add a new method to our Circle class. This will be a simple method called FillCircle.
public void FillCircle()
{
    Console.WriteLine("Filling CIRCLE at {0},{1}", m_xpos, m_ypos);
}
Using the example from up-casting, we know that we are able to write the following:
Shape s = new Circle(100, 100);
We are then free to call the Draw method. Having added the FillCircle method to our Circle class, are we able to call this method by doing the following?
s.FillCircle ();
In short, the answer is no. Because we have cast Circle to the type Shape, we are only able to use methods found in Shape, that is, Circle has inherited all the properties and methods of Shape. If we want to call FillCircle, we need to down-cast our type to Circle. Why is it called down-casting? Quite simply, we are moving down the object hierarchy, from Shape down to Circle.
So how do we code a down-cast from Shape to Circle? The code for doing this is quite simple:
Circle c;
c = (Circle)s;
Simply, we are declaring c as the type Circle and explicitly casting s to this type. We are now able to call the FillCircle method by doing the following:
c.FillCircle();
This gives us the following output:
Drawing a CIRCLE at 100,100
Filling CIRCLE at 100,100
We could also write ((Circle)s).FillCircle() reducing the lines of code needed to down-cast our type and call the required method.
Down-casting is potentially unsafe, because you could attempt to use a method that the derived class does not actually implement. With this in mind, down-casting is always explicit, that is, we are always specifying the type we are down-casting to. 

The as and is keywords

To demonstrate as and is, lets implement a FillSquare method in our Square class. Our code could be:
Public void FillSquare()
{
    Console.WriteLine("Filling SQUARE at {0},{1}", m_xpos, m_ypos);
}
Taking some code from our polymorphism example, as follows:
class Program
{
        static void Main(string[] args)
        {
            Shape[] shapes = new Shape[3];
            shapes[0] = new Shape(100, 100);
            shapes[1] = new Square(200, 200);
            shapes[2] = new Circle(300, 300);
            foreach (Shape shape in shapes)
                shape.Draw();
           
        }
}
We have Circle and Square in our array of type Shape. How do we know what type we have to down-cast to in order to call the correct routine to fill the shape?
Within the foreach statement, we have to test the type of shape being drawn before we down-cast, we will use the is keyword to test type. We will modify the code above, to ensure the correct method is called to fill our shapes as they are drawn.
foreach (Shape shape in shapes)
{
    shape.Draw();
    if (shape is Circle)
        ((Circle)shape).FillCircle();
        if (shape is Square)
            ((Square)shape).FillSquare();
}  
Within the loop, we are performing a test to see if the type of shape is a Circle or a Square, depending on the result, we are down-casting our type in order to call the correct fill routine. Our output now is:
Drawing a SHAPE at 100,100 Drawing a SQUARE at 200,200 Filling SQUARE at 200,200
Drawing a CIRCLE at 300,300
Filling CIRCLE at 300,300
I have highlighted the changes our code has made to the output. The alternative to the is keyword is as. We can write:
Circle c = shape as Circle;
The difference is that as tries to cast shape to a type (in our example Circle). If the cast fails, c is set to null. For example:
Circle c = shape as Circle;
If(c!=null)
  c.FillCircle(); 

Conclusion

Quite a lot of ground has been covered in this article. Whilst the polymorphism example is very simple, it gives you an understanding of what polymorphism is and how you could implement it in your design.
The down-casting example is a little contrived. Some of you may be thinking why not just implement a base class method for filling the shapes and override it in the derived classes. The idea of implementing the fill routines as I did was to aid in the explanation of down-casting and has only been done for this reason.
I hope you have enjoyed reading this article and have learned something from it.
Q:- We can boxing (value type to object) Upcasting , unboxing (object to value) Downcasting. this is posible since compiler allready know type before conversion (int to object)(object to int), Object is base class for all class in .net framework So this downcasting possible, So Can we convert one User defined datatype (Child class) to another custom data type (Parent) Downcasting
You can only unbox/cast object to int if that object actually is a boxed int:
int value = 10;
object boxedValue = (object)value;
int unboxedValue = (int)boxedValue; // works
object nonIntObject = "a string";
int unboxedValue = (int)nonIntObject; // does not work
And there's exactly the same thing with reference types and casting. You can explicitly cast child class to parent class only if the instance is actually downcasted child class instance (or class derived from child class).
Customer value = new GoldCustomer();
GoldCustomer childValue = (GoldCustomer)value; // works
Customer value = new Customer();
GoldCustomer childValue = (GoldCustomer)value; // does not work
Customer value = new Customer(); GoldCustomer childValue = (GoldCustomer)value; // does not work It will not work simply because childValue is a incomplete object which has only parent memory block not his part of child.
Customer value = new GoldCustomer(); GoldCustomer childValue = (GoldCustomer)value; // works because now child object pointing its own type actually and its has full memory block part of base plus child, one more thing it can also do not it can call its own part too means child call specific property.
Child is type of base so it is possible. Type compatibility
class Program1
    {
        public  class Base
        {
            public  void Show()
            {       Console.WriteLine("This is Base Class.");  }
        }
        public class Derived : Base
        {
            public  void Show()
            { Console.WriteLine("This is Derived Class."); }
        }
        static void Main(string[] args)
        {
            Base objBaseReference = new Base();
            objBaseReference.Show();// Output ---> This is Base Class.
            Base objBaseReferenceToderive = new Derived();
            objBaseReferenceToderive.Show();// Output ---> This is Base Class.
            //Derived d = (Derived)objBaseReference;//Runtime error Invalid cast exception
            Console.ReadLine();
        }
    }
Type Casting and Type Conversion
using System;
using System.Collections.Generic;
using System.Text;
namespace castingCodeSnippets
{
    // dummy classes to demonstrate conversions --------
    class Base
    {
    }
    class Derived : Base
    {
    }  
    // Rational class implementing the implicit and explicit conversion operators------
    class Rational
    {
        int numerator;
        int denominator;
        public Rational(int num, int den)
        {
            numerator = num;
            denominator = den;
        }
        public static implicit operator Rational(int i)
        {
            // since the rational equivalant of an int has 1 as denominator
            Rational rational = new Rational(i, 1);
            return rational;
        }
        public static explicit operator double(Rational r)
        {
            double result = ((double)r.numerator) / r.denominator;
            return result;
        }
    }
    class Program
    {
        // Note: Dummy parenthesis are used to limit the scope of variable to avoid name conflicts.
        // No output from this application. Please use breakpoints and debug it to get understanding.
        static void Main(string[] args)
        {
            // IMPLICIT CONVERSIONS ------------------------------------------------------------------
            {
                int i = 10;
                long l = i;
                Derived d = new Derived();
                Base b = d;
            }
            // EXPLICIT CONVERSIONS--Downcasting-----------------------------------------------------------------
            {
                long l = 10;
                int i = (int)l;
                Base b = new Base();
           //     Derived d = (Derived)b; // this will throw an exception.
            }
            // is operator ---------------------------------------------------------------------------
            {
                // CASE 1 *****
                // This will work fine as o1 is actually an int
                object o1 = 1;
                int i = (int)o1;
                // CASE 2 *****
                // This wont work because o2 is not an int so we need
                // to have an is oprerator before the actual cast
                object o2 = "1";
                int j;
                if (o2 is int)
                {
                    j = (int)o2;
                }
                // CASE 3 *****
                // We can never know what is the atual type of
                // an object at runtime so its always better to use
                // is operator, rewriting the first case
                object o3 = 1;
                int k;
                if (o3 is int)
                {
                    k = (int)o3;
                }
            }
            // as operator ------------------------------------------------------------------------------
            {
                object o3 = 1;
                int? k = o3 as int?;
                if (k != null)
                {
                    //use k for whatever we want to
                    Console.WriteLine(k.Value);
                }
            }
            // DEMO OF USER DEFINED CONVERSIONS -----------------------------------------------------
            {
                // Conversion from int to rational is implicit
                Rational r1 = 23;
                //Conversion from rational to double is explicit
                Rational r2 = new Rational(3, 2);
                double d = (double)r2;
            }
            // DEMO OF HELPER FUNCTION(STRING TO INT)------------------------------------------------
            string s = "123";
            try
            {
                int i = Convert.ToInt32(s);
            }
            catch (Exception)
            {
                // Pokemon exception handling, ideally recfication
                // code and logging should be done here
            }
        }
    }
}
Implicit casts
Let us start by looking into the conversions that are done automatically by C#. Implicit casts are the casts that does not require the programmer to do an explicit conversion. One data type can simply be assigned to another. There are some rules that govern the implicit cast.
Built-in numeric types, widening conversions.
Reference types, Derived class to base class.
The built in numeric types can be assigned to each other if a narrow type is being assigned to wider type. This is possible because the compiler know that the only problem in such operations is that a little more memory will be needed to hold this type and no data will be truncated or lost. So the following conversion will not need any explicit cast.
 Collapse | Copy Code
int i = 10;
long l = i;
Secondly, If we try to assign a value from derived class to a base class it will work. that is because a derived class always is-a base class. Also, from a memory perspective a base class variable pointing to a derived class object can safely access the base class part of the object in memory without any problem. SO following code will work without needing any explicit casts.
 Collapse | Copy Code
class Base
{
}
class Derived : Base
{
}  
class Program
{
    static void Main(string[] args)
    {
        Derived d = new Derived();
        Base b = d;      
    }
}
Other then these two possible scenarios, all the conversions will create compile time errors. Still, If we need to perform the conversions, we will have to use explicit casting/conversion.
Explicit casts
If we find ourselves in need of conversion that is either narrowing conversion or conversion between unrelated types then we will have to use explicit conversions. Using explicit conversions we are actually letting the compiler know that we know there is possible information loss but still we need to make this conversion. So if we need to convert a long type to an integer type we need to cast it explicitly.
 Collapse | Copy Code
long l = 10;
int i = (int)l;
On similar lines, if we need to cast a base class to a derived class I will have to cast it explicitly.
 Collapse | Copy Code
Base b = new Base();
Derived d = (Derived)b;
Explicit casting actually tells the compiler that we know about possible information loss/mismatch but still we need to perform this cast. This is ok for inbuilt numeric types but in case of reference types, there is a possibility that the types are not at all compatible i.e. casting from one type to another is not at all possible. For example casting a string "abc" to Integer is not possible.
Such casting expressions will compile successfully but they will fail at run-time. What C# compiler does it that it checks whether these two types are cast compatible or not and if not it raises an exception InvalidCastException.
'is' and 'as' operators
So whenever we are using explicit casts, it is always a good idea to wrap the cast inside a try-catch block. C# also provides is and as operators which are helpful in performing explicit casts in an exception safe manner.
The is operator checks whether the type being casted from is compatible to the type being casted to and returns a boolean value. So the exception safe way to perform an explicit cast using is operator would be
 Collapse | Copy Code
static void Main(string[] args)
{  
    // CASE 1 *****
    // This will work fine as o1 is actually an int
    object o1 = 1;
    int i = (int)o1;
    // CASE 2 *****
    // This wont work because o2 is not an int so we need
    // to have an is oprerator before the actual cast
    object o2 = "1";
    int j;
    if (o2 is int)
    {
        j = (int)o2;
    }
    // CASE 3 *****
    // We can never know what is the atual type of
    // an object at runtime so its always better to use
    // is operator, rewriting the first case
    object o3 = 1;
    int k;
    if (o3 is int)
    {
        k = (int)o3;
    }
}
Case 1 in the above code snippet will throw an exception is o1 is assigned to some type that is not int. the other 2 cases are exception safe and will only perform the cast if the types are compatible for casting.
There is one small performance issue in using is operator. Case 3 in above code snippet will work fine but it involves accessing the object twice. Once for checking the compatibility i.e. the is operator and secondly to actually extracting out the value i.e. casting. can we not have something like - "Check the compatibility and if compatible perform the cast" in one single operation. That is where the as operator comes in picture.
The as operator checks the compatibility and if its OK it will perform the cast too. If the cast is not compatible or unsuccessful then the result will be null. so the above cast can be rewritten using the as operator
 Collapse | Copy Code
object o3 = 1;
int? k = o3 as int?;
if (k != null)
{
    //use k for whatever we want to
    Console.WriteLine(k.Value);
}
Note: The important thing to note here is that the as operator can only be used with reference types. This is the reason we used nullable int in the above example.
So if we need to have an exception safe casting, we can use is or as operator. We should use is operator if the target type is a value type and as operator if the target type is a reference type.
User defined conversions
C# also provides the flexibility for defining conversions on classes and structs so that they can be converted to and from other. The conversion operators simply contains the logic of how the conversion should happen. We can define these conversion operators to be implicit or explicit. If we define them implicit the conversion will happen without needing as explicit cast. if we define it as explicit the casting will be required.
Let us try to see how we can implement these conversion operations. Let us implement a small class Rational to hold rational number. We will then define two conversion operations. Int to Rational (an implicit conversion) and Rational to double (an explicit conversion).
 Collapse | Copy Code
class Rational
{
    int numerator;
    int denominator;
    public Rational(int num, int den)
    {
        numerator = num;
        denominator = den;
    }
    public static implicit operator Rational(int i)
    {
        // since the rational equivalant of an int has 1 as denominator
        Rational rational = new Rational(i, 1);
        return rational;
    }
    public static explicit operator double(Rational r)
    {
        double result = ((double)r.numerator) / r.denominator;
        return result;
    }
}
And now let us see how we can use these conversion operators to perform actual conversions.
 Collapse | Copy Code
static void Main(string[] args)
{  
    // Conversion from int to rational is implicit
    Rational r1 = 23;
    // Conversion from rational to double is explicit
    Rational r2 = new Rational(3, 2);
    double d = (double)r2;
}
Before wrapping up, there is one more thing that the beginners should be aware of. there are a lot of helper classes and helper functions available in C# to perform the frequently needed conversions. It is always a good idea to refer to the documentation to achieve the desired conversions before putting in the code for conversions. Following code snippet shows how we can convert string to int using Convert class.
 Collapse | Copy Code
static void Main(string[] args)
    string s = "123";
    try
    {
        int i = Convert.ToInt32(s);
    }
    catch (Exception ex)
    {
        // Pokemon exception handling, ideally rectification
        // code and logging should be done here
    }   
}
Int32 x = 5;
object o = x; // Implicit Boxing
x = o; // Implicit UnBoxing  
Int32 x = 5;
object o = x; // Implicit Boxing
x = (Int32)o; // Explicit UnBoxing  
Function declared as abstract only has declaration.
Abstract Function shud only be declare in the abstract class. Abstract class can have normal as well as abstract function.
  class Program1
    {
        public  class Base//Error               'CsharpPrograms.Program1.Base.Show()' is abstract but it is contained in non-abstract class
        {
             public abstract void Show() //Error         cannot declare a body because it is marked abstract
            {
                Console.WriteLine("This is Base Class.");
            }
        }
        public class Derived : Base
        {
            public override void Show()
            {
                Console.WriteLine("This is Derived Class.");
            }
        }
        static void Main(string[] args)
        {
           
        }
   
    }                         *******************
    class Program1
    {
        public  class Base
        {
            public  void Show()
            {       Console.WriteLine("This is Base Class.");  }
        }
        public class Derived : Base
        {
            public  void Show()
            { Console.WriteLine("This is Derived Class."); }
        }
        static void Main(string[] args)
        {
            Base objBaseReference = new Base();
            objBaseReference.Show();// Output ---> This is Base Class.
            Base objBaseReferenceToderive = new Derived();//from a memory perspective a base class variable pointing to a derived class object can safely access the base class part of the object in memory without any problem. SO following code will work without needing any explicit casts.
            objBaseReferenceToderive.Show();// Output ---> This is Base Class.
            //Derived d = (Derived)objBaseReference;//Runtime error Invalid cast exception
            Console.ReadLine();
        }
    }
***************



No comments:

Post a Comment