Monday 25 February 2013

Operator Overloading

   It is an approach of defining multiple behaviors to an operator just like we can define multiple behaviors to a method in method overloading.
   In method overloading a method will have different behaviors that are defined basing on the parameter types of that method. In the same way in operator overloading, a operator will have different behaviors based on the operands between which we use the operators.
   For example '+' is an overloaded operator which works as additional operator when used between two numeric operands and works as a concatenation operator when used with the string operands or string-numeric operands.
numeric+numeric=addition
string+string=concatenation
string+numeric=concatenation
   Same as we discussed about we can also add new behavior to  existing operators of the language by defining an operator method on that operator as following:
[<modifiers>] static <types> operator <opt> (<operand types>)
    A operator method must b defined as static only. Type refers to the data-type of the value what it returns when the operator is used between two operands. Operator is a keyword which tells we are defining an operator method. <opt> refers to the type of operands between which we want to use the operator.

Example of Operator Overloading


// Add a new class Matrix.cs
using System;
namespace CSharpConsole
{
    class Matrix
    {

        //declaring variables for a 2*2 matrix
        int a, b, c, d;
        public Matrix(int a, int b, int c, int d)
        {
            //initializing the matrix varaibles
            this.a=a ; this.b=b ;
            this.c=c ; this.d=d ;
        }

        // overloading the + operator so that it can be used for adding values of 2 matrix
        public static Matrix operator + (Matrix m1, Matrix m2)
        {
            Matrix obj = new Matrix(m1.a + m2.a, m1.b + m2.b, m1.c + m2.c, m1.d + m2.d);
            return obj;
        }

        // overloading the - operator so that it can be used for substracting values of 2 matrix
        public static Matrix operator -(Matrix m1, Matrix m2)
        {
            Matrix obj = new Matrix(m1.a - m2.a, m1.b - m2.b, m1.c - m2.c, m1.d - m2.d);
            return obj;
        }

        //overriding the ToString method inherited from object class for returning the values associated with matrix object
        public override string ToString()
        {
            return string.Format("[a:{0};b:{1};c:{2}:d:{3}]", a,b,c,d );
        }
    }
}
// Add another class TestMatrix to test the above code.

using System;
namespace CSharpConsole
{
    class TestMatrix
    {
        static void Main()
        {
            Matrix m1 = new Matrix(5, 6, 7, 8);
            Matrix m2 = new Matrix(1, 2, 3, 4);
            Matrix m3 = m1 + m2;
            Matrix m4 = m1 - m2;
            Console.WriteLine(m1);
            Console.WriteLine(m2);
            Console.WriteLine(m3);
            Console.WriteLine(m4);
            Console.ReadLine();
        }
    }
}

Sealed Classes and Sealed Methods

  • Sealed Classes: A Class which is defined by using the sealed modifier is a sealed class but if any class is declared as sealed the class cannot be inherited by any other class 
           for example:
           sealed class class1
           class2:class1    //Invalid
Note: We can still consume a sealed class from any other class by creating the object even if inheritance is not possible.
  • Sealed Methods: A method which cannot be overridden under child classes is called as Sealed Methods and by default every method of a class is a sealed method because overriding a child class under parent class is possible only when the method is declared as virtual.
            If a method is declared as virtual under a class, any child class of the class linear hierarchy has a right to override the method. 
       class1
       public virtual void show()
       class2:class1    
       public override void show()
       class3:class2
       public override void show()
Note: In the above case even if class2 does not override the method then also class3 can override the method.

Method Overriding

If at all a parent classes method is re-implemented under a child class exactly with the same signature we call it as Method  Overriding.

How to override a parent classes method under child class ?
  • If we want to override any parent classes method under child class first under the parent the method must be defined using virtual modifier. Declaring a method as virtual under a class is giving a permission for its child classes to override.
  • The methods that are declared as virtual can be overwritten as child classes using a override modifier.
      class1
      public virtual void Show()  // overridable
      class 2:class1
      public override void Show() // overriding

Add a class LoadParent.cs and write the following code
using System;
namespace CSharpConsole
{
    class LoadParent
    {
        public void Test()
        {
            Console.WriteLine("Parent's test method");
        }
        public virtual void  Show() //  overridable
        {
            Console.WriteLine("Parent's show method");
        }
        public void Display()
        {
            Console.WriteLine("Parent's display method");
        }
    }
}
// Add a class loadchild.cs and write the following code
using System;
namespace CSharpConsole
{
    class loadchild: LoadParent
    {
       // overloading parent's test method
        public void Test(int x)
        {
            Console.WriteLine("Child's test method ");
        }
       public override  void Show()
        {
            Console.WriteLine("Child's show method ");
        }
       public new void Display()
       {
            Console.WriteLine("Child's display method");
       }
       static void Main()
       {
           loadchild c = new loadchild();
           c.Test();
           c.Test(10);
           c.Show();
           c.Display();
           Console.ReadLine();
       }
   }
}

Types of Polymorphism

Polymorphism is divided into 2 categories
  • Compiletime Polymorphism (also called as Static Polymorphism or Early Binding)
  • Runtime Polymorphism (also called as Non-Static Polymorphism or Late Binding)
        In the first case the object of the class will identify for a particular method call which polymorphic method has to be executed and binds the method call with its method definition and executes this method in runtime but only the method will be bound. This type of binding takes place in Overloading because in overloading we have multiple methods with same name but different signature so each method is unique to itself so while binding the method definition we can identify the unique keyword.
       In the second case ie Runtime Polymorphism the object of a class recognizes which polymorphic method it has to call in runtime and this kind of identification takes pace in Overriding and Hiding as there are multiple methods with the same name and same signature with both the cases so that  the object will identify which exact method has to be executed in runtime only being on the hierarchy of the class.