Thursday 19 December 2013

Polymorphism

When a message can be processed in different ways is called polymorphism. Polymorphism means many forms.
Polymorphism is one of the fundamental concepts of OOP.
Polymorphism provides following features: 
  • It allows you to invoke methods of derived class through base class reference during runtime.
  • It has the ability for classes to provide different implementations of methods that are called through the same name. 
Polymorphism is of two types:
 1.Compile time polymorphism/Overloading
 2. Runtime polymorphism/Overriding

Compile Time Polymorphism:
Compile time polymorphism is method and operators overloading. It is also called early binding.
 In method overloading method performs the different task at the different input parameters.

Function overloading in C++:


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 can not 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:

#include <iostream>
using namespace std;
 
class printData 
{
   public:
      void print(int i) {
        cout << "Printing int: " << i << endl;
      }

      void print(double  f) {
        cout << "Printing float: " << f << endl;
      }

      void print(char* c) {
        cout << "Printing character: " << c << endl;
      }
};

int main(void)
{
   printData pd;
 
   // Call print to print integer
   pd.print(5);
   // Call print to print float
   pd.print(500.263);
   // Call print to print character
   pd.print("Hello C++");
 
   return 0;
}
When the above code is compiled and executed, it produces the following result:
Printing int: 5
Printing float: 500.263
Printing character: Hello C++

Operators overloading in C++:

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.

Box operator+(const Box&);
declares the addition operator that can be used to add two Box objects and returns final Box object. Most overloaded operators may be defined as ordinary non-member functions or as class member functions. In case we define above function as non-member function of a class then we would have to pass two arguments for each operand as follows:
Box operator+(const Box&, const Box&);
Following is the example to show the concept of operator over loading using a member function. Here an object is passed as an argument whose properties will be accessed using this object, the object which will call this operator can be accessed using this operator as explained below:

#include <iostream>
using namespace std;

class Box
{
   public:

      double getVolume(void)
      {
         return length * breadth * height;
      }
      void setLength( double len )
      {
          length = len;
      }

      void setBreadth( double bre )
      {
          breadth = bre;
      }

      void setHeight( double hei )
      {
          height = hei;
      }
      // Overload + operator to add two Box objects.
      Box operator+(const Box& b)
      {
         Box box;
         box.length = this->length + b.length;
         box.breadth = this->breadth + b.breadth;
         box.height = this->height + b.height;
         return box;
      }
   private:
      double length;      // Length of a box
      double breadth;     // Breadth of a box
      double height;      // Height of a box
};
// Main function for the program
int main( )
{
   Box Box1;                // Declare Box1 of type Box
   Box Box2;                // Declare Box2 of type Box
   Box Box3;                // Declare Box3 of type Box
   double volume = 0.0;     // Store the volume of a box here
 
   // box 1 specification
   Box1.setLength(6.0); 
   Box1.setBreadth(7.0); 
   Box1.setHeight(5.0);
 
   // box 2 specification
   Box2.setLength(12.0); 
   Box2.setBreadth(13.0); 
   Box2.setHeight(10.0);
 
   // volume of box 1
   volume = Box1.getVolume();
   cout << "Volume of Box1 : " << volume <<endl;
 
   // volume of box 2
   volume = Box2.getVolume();
   cout << "Volume of Box2 : " << volume <<endl;

   // Add two object as follows:
   Box3 = Box1 + Box2;

   // volume of box 3
   volume = Box3.getVolume();
   cout << "Volume of Box3 : " << volume <<endl;

   return 0;
}
When the above code is compiled and executed, it produces the following result:
Volume of Box1 : 210
Volume of Box2 : 1560
Volume of Box3 : 5400

Overloadable/Non-overloadableOperators:

Following is the list of operators which can be overloaded:

+
-
*
/
%
^
&
|
~
!
,
=
<
>
<=
>=
++
--
<<
>>
==
!=
&&
||
+=
-=
/=
%=
^=
&=
|=
*=
<<=
>>=
[]
()
->
->*
new
new []
delete
delete []
Following is the list of operators, which can not be overloaded:
::
.*
.
?:

Operator Overloading Examples:

Here are various operator overloading examples to help you in understanding the concept.
S.N.
Operators and Example
1
Unary operators overloading
2
Binary operators overloading
3
Relational operators overloading
4
Input/Output operators overloading
5
++ and -- operators overloading
6
Assignment operators overloading
7
Function call () operator overloading
8
Subscripting [] operator overloading
9
Class member access operator -> overloading

When and why to use method overloading 
Use method overloading in situation where you want a class to be able to do something, but there is more than one possibility for what information is supplied to the method that carries out the task.
You should consider overloading a method when you for some reason need a couple of methods that take different parameters, but conceptually do the same thing.


Runtime Time Polymorphism

Runtime time polymorphism is done using inheritance and virtual functions. Method overriding is called runtime polymorphism. It is also called late binding.

When overriding a method, you change the behavior of the method for the derived class. Overloading a method simply involves having another method with the same prototype.

Caution: Don't confused method overloading with method overriding, they are different, unrelated concepts. But they sound similar.

Method Overriding:

Whereas Overriding means changing the functionality of a method without changing the signature. We can override a function in base class by creating a similar function in derived class. This is done by usingvirtual/override keywords.

Base class method has to be marked with virtual keyword and we can override it in derived class usingoverride keyword.

Derived class method will completely overrides base class method i.e. when we refer base class object created by casting derived class object a method in derived class will be called.


The word polymorphism means having many forms. Typically, polymorphism occurs when there is a hierarchy of classes and they are related by inheritance.
C++ polymorphism means that a call to a member function will cause a different function to be executed depending on the type of object that invokes the function.
Consider the following example where a base class has been derived by other two classes:
#include <iostream> 
using namespace std;
 
class Shape {
   protected:
      int width, height;
   public:
      Shape( int a=0, int b=0)
      {
         width = a;
         height = b;
      }
      int area()
      {
         cout << "Parent class area :" <<endl;
         return 0;
      }
};
class Rectangle: public Shape{
   public:
      Rectangle( int a=0, int b=0)
      {
        Shape(a, b); 
      }
      int area ()
      { 
         cout << "Rectangle class area :" <<endl;
         return (width * height); 
      }
};
class Triangle: public Shape{
   public:
      Triangle( int a=0, int b=0)
      {
        Shape(a, b); 
      }
      int area ()
      { 
         cout << "Triangle class area :" <<endl;
         return (width * height / 2); 
      }
};
// Main function for the program
int main( )
{
   Shape *shape;
   Rectangle rec(10,7);
   Triangle  tri(10,5);

   // store the address of Rectangle
   shape = &rec;
   // call rectangle area.
   shape->area();

   // store the address of Triangle
   shape = &tri;
   // call triangle area.
   shape->area();
   
   return 0;
}

When the above code is compiled and executed, it produces the following result:
Parent class area
Parent class area

The reason for the incorrect output is that the call of the function area() is being set once by the compiler as the version defined in the base class. This is called static resolution of the function call, orstatic linkage - the function call is fixed before the program is executed. This is also sometimes calledearly binding because the area() function is set during the compilation of the program.

But now, let's make a slight modification in our program and precede the declaration of area() in the Shape class with the keyword virtual so that it looks like this:

class Shape {
   protected:
      int width, height;
   public:
      Shape( int a=0, int b=0)
      {
         width = a;
         height = b;
      }
      virtual int area()
      {
         cout << "Parent class area :" <<endl;
         return 0;
      }
};

After this slight modification, when the previous example code is compiled and executed, it produces the following result:
Rectangle class area
Triangle class area

This time, the compiler looks at the contents of the pointer instead of it's type. Hence, since addresses of objects of tri and rec classes are stored in *shape the respective area() function is called.
As you can see, each of the child classes has a separate implementation for the function area(). This is how polymorphism is generally used. You have different classes with a function of the same name, and even the same parameters, but with different implementations.

Virtual Function:

virtual function is a function in a base class that is declared using the keyword virtual. Defining in a base class a virtual function, with another version in a derived class, signals to the compiler that we don't want static linkage for this function.
What we do want is the selection of the function to be called at any given point in the program to be based on the kind of object for which it is called. This sort of operation is referred to as dynamic linkage, or late binding.

Pure Virtual Functions:

It's possible that you'd want to include a virtual function in a base class so that it may be redefined in a derived class to suit the objects of that class, but that there is no meaningful definition you could give for the function in the base class.
We can change the virtual function area() in the base class to the following:

class Shape {
   protected:
      int width, height;
   public:
      Shape( int a=0, int b=0)
      {
         width = a;
         height = b;
      }
      // pure virtual function
      virtual int area() = 0;
};
The = 0 tells the compiler that the function has no body and above virtual function will be called pure virtual function.

More discuss about virtual function in virtual blog.


Inheritance

One of the most important concepts in object-oriented programming is that of inheritance. Inheritance allows us to define a class in terms of another class, which makes it easier to create and maintain an application. This also provides an opportunity to reuse the code functionality and fast implementation time.
When creating a class, instead of writing completely new data members and member functions, the programmer can designate that the new class should inherit the members of an existing class. This existing class is called the base class, and the new class is referred to as the derived class.
The idea of inheritance implements the is a relationship. 
For example, mammal IS-A animal, dog IS-A mammal hence dog IS-A animal as well and so on.

-> Just like abstraction is closely related with generalization, the inheritance is closely related with specialization. It is important to discuss those two concepts together with generalization to better understand and to reduce the complexity.
->One of the most important relationships among objects in the real world is specialization, which can be described as the “is-a” relationship. When we say that a dog is a mammal, we mean that the dog is a specialized kind of mammal. It has all the characteristics of any mammal (it bears live young, nurses with milk, has hair), but it specializes these characteristics to the familiar characteristics of canis domesticus. A cat is also a mammal. As such, we expect it to share certain characteristics with the dog that are generalized in Mammal, but to differ in those characteristics that are specialized in cats.
->The specialization and generalization relationships are both reciprocal and hierarchical. Specialization is just the other side of the generalization coin: Mammal generalizes what is common between dogs and cats, and dogs and cats specialize mammals to their own specific subtypes.


Purpose Of Inheritance:
  1. Code Re-usability (40 %)
  2. Method Overriding (i.e. Run Time Poymorphism) using virtual keyword (60 %).

Base & Derived Classes:

A class can be derived from more than one classes, which means it can inherit data and functions from multiple base classes. To define a derived class, we use a class derivation list to specify the base class(es). A class derivation list names one or more base classes and has the form:
class derived-class: access-specifier base-class

Where access-specifier is one of public, protected, or private, and base-class is the name of a previously defined class. If the access-specifier is not used, then it is private by default.
Consider a base class Shape and its derived class Rectangle as follows:
#include <iostream>
 
using namespace std;

// Base class
class Shape 
{
   public:
      void setWidth(int w)
      {
         width = w;
      }
      void setHeight(int h)
      {
         height = h;
      }
   protected:
      int width;
      int height;
};

// Derived class
class Rectangle: public Shape
{
   public:
      int getArea()
      { 
         return (width * height); 
      }
};

int main(void)
{
   Rectangle Rect;
 
   Rect.setWidth(5);
   Rect.setHeight(7);

   // Print the area of the object.
   cout << "Total area: " << Rect.getArea() << endl;

   return 0;
}
When the above code is compiled and executed, it produces the following result:
Total area: 35

Access Control and Inheritance:

A derived class can access all the non-private members of its base class. Thus base-class members that should not be accessible to the member functions of derived classes should be declared private in the base class.
We can summarize the different access types according to who can access them in the following way:
Access
public
protected
private
Same class
yes
yes
yes
Derived classes
yes
yes
no
Outside classes
yes
no
no
A derived class inherits all base class methods with the following exceptions:
  • Constructors, destructors and copy constructors of the base class.
  • Overloaded operators of the base class.
  • The friend functions of the base class.

When deriving a class from a base class, the base class may be inherited through public, protected orprivate inheritance. The type of inheritance is specified by the access-specifier as explained above.
We hardly use protected or private inheritance, but public inheritance is commonly used. While using different type of inheritance, following rules are applied:
  • Public Inheritance: When deriving a class from a public base class, public members of the base class become public members of the derived class and protected members of the base class become protected members of the derived class. A base class's private members are never accessible directly from a derived class, but can be accessed through calls to the publicand protected members of the base class.
  • Protected Inheritance: When deriving from a protected base class, public and protectedmembers of the base class become protected members of the derived class.
  • Private Inheritance: When deriving from a private base class, public and protected members of the base class become private members of the derived class.
What is inherited?

When inheritance is done, various links and tables (index, virtual etc) are created which are used to provide the accessibility of the members of the base class in derived class and in other class hierarchy. This means saying “public members are inherited” is better to say as “public members become accessible”.
A derived class inherits every member of a base class except:
  • its constructor and its destructor
  • its friends
  • its operator=() members

Types of Inheritance

There are five different inheritances supported in C++:
  • (1) Simple / Single
  • (2) Multilevel
  • (3) Hierarchical
  • (4) Multiple
  • (5) Hybrid














Multiple Inheritances:

A C++ class can inherit members from more than one class and here is the extended syntax:
class derived-class: access baseA, access baseB....
Where access is one of public, protected, or private and would be given for every base class and they will be separated by comma as shown above. Let us try the following example:

#include <iostream>
 
using namespace std;

// Base class Shape
class Shape 
{
   public:
      void setWidth(int w)
      {
         width = w;
      }
      void setHeight(int h)
      {
         height = h;
      }
   protected:
      int width;
      int height;
};

// Base class PaintCost
class PaintCost 
{
   public:
      int getCost(int area)
      {
         return area * 70;
      }
};

// Derived class
class Rectangle: public Shape, public PaintCost
{
   public:
      int getArea()
      { 
         return (width * height); 
      }
};

int main(void)
{
   Rectangle Rect;
   int area;
 
   Rect.setWidth(5);
   Rect.setHeight(7);

   area = Rect.getArea();
   
   // Print the area of the object.
   cout << "Total area: " << Rect.getArea() << endl;

   // Print the total cost of painting
   cout << "Total paint cost: $" << Rect.getCost(area) << endl;

   return 0;
}
When the above code is compiled and executed, it produces the following result:
Total area: 35
Total paint cost: $2450

Execution order of the constructor and destructor in inheritance.

It is sometimes the case that classes are derived from other classes, which are themselves derived from other classes. For example:


































class A
{
public:
    A()
    {
        cout << "A" << endl;
    }
};

class B: public A
{
public:
    B()
    {
        cout << "B" << endl;
    }
};

class C: public B
{
public:
    C()
    {
        cout << "C" << endl;
   }
}; 


class D: public C
{
public:
    D()
    {
        cout << "D" << endl;
    }
};

Remember that C++ always constructs the “first” or “most base” class first. It then walks through the inheritance tree in order and constructs each successive derived class.
Here’s a short program that illustrates the order of creation all along the inheritance chain.















int main()
{
    cout << "Constructing A: " << endl;
    A cA;

    cout << "Constructing B: " << endl;
    B cB;

    cout << "Constructing C: " << endl;
    C cC;

    cout << "Constructing D: " << endl;
    D cD;
}
This code prints the following:
Constructing A:
A
Constructing B:
A
B
Constructing C:
A
B
C
Constructing D:
A
B
C
D

Note:

Base class constructors and derived class destructors are called first


Basically, it's a test to see if you know in what order the constructors and destructors will be called when a program deals with inheritance. 

class Base
{
  public:

  Base ( )
  {
    cout << "Inside Base constructor" << endl;
  } 

  
  ~Base ( )
  {
    cout << "Inside Base destructor" << endl;
  } 

};

class Derived : public Base
{

  public:

  Derived  ( )
  {
    cout << "Inside Derived constructor" << endl;
  } 

  ~Derived ( )
  {
    cout << "Inside Derived destructor" << endl;
  } 

};

void main( )
{
  Derived x;
}
In the code above, when the object "x" is created, first the Base class constructor is called, and after that the Derived class constructor is called. Because the Derived class inherits from the Base class, both the Base class and Derived class constructors will be called when a Derived class object is created.
When the main function is finished running, the object x's destructor will get called first, and after that the Base class destructor will be called.
So, here is what the output of the code above would look like:
Inside Base constructor
Inside Derived constructor
Inside Derived destructor
Inside Base destructor


Note:
Common Interview Question: Are private class members inherited to the derived class?

Ans: Yes, the private members are also inherited in the derived class but we will not be able to access them. Trying to access a private base class member in the derived class will report a compile time error.
class A
{
public :
void fun1 ()
{
}
private:
 void fun2 ()
{
}
};

class B:  public A
{
};

void main ()
{
B B1 = new B ();
B1.fun1 ();
//Error, Cannot access private member fun2
//B1.fun2 ();
}
}

Method Hiding and Inheritance We will look at an example of how to hide a method in C++. The Parent class has a write () method which is available to the child class. In the child class I have created a new write () method. So, now if I create an instance of child class and call the write () method, the child class write () method will be called. The child class is hiding the base class write () method. This is called method hiding.

If we want to call the parent class write () method, we would have to type cast the child object to Parent type and then call the write () method as shown in the code snippet below.

class Parent
{
    public:
 void write ()
    {
        cout<< "Parent Class write method";
    }
};
class Child: public Parent
{
    public:
  void write ()
    {
       cout<<"Child Class write method";
    }
   };

    void main ()
    {
        Child c1 = new Child ();
        c1.write ();
        //Type caste c1 to be of type Parent and call write () method
        ((Parent) C1).write ();
    }

UpCasting:

Upcasting is using the Super class's reference or pointer to refer to a Sub class's object. Or we can say that, the act of converting a Sub class's reference or pointer into its Super class's reference or pointer is called Upcasting.





















class Super
{
 int x;


public:

void funBase() { cout << "Super function"; }

};

class Sub : public Super


{
int y;
};


int main()


{


Super* ptr; // Super class pointer


Sub obj;


ptr = &obj;


Super &ref; // Super class's reference


ref=obj;








}

The opposite of Upcasting is Downcasting, in which we convert Super class's reference or pointer into derived class's reference or pointer. We will study more about Downcasting later

Functions that are never Inherited

1. Constructors and Destructors are never inherited and hence never overrided.
2. Also, assignment operator = is never inherited. It can be overloaded but can't be inherited by sub class.

Inheritance and Static Functions

  1. They are inherited into the derived class.
  2. If you redefine a static member function in derived class, all the other overloaded functions in base class         are hidden.
  3. Static Member functions can never be virtual. We will study about Virtual in coming topics.