Interface in C#

Interfaces are very interesting and are a confusing topic in the C# language.

What an Interface is

We can define an interface in many terms like:

  1. An interface is defined as a syntactical contract that all the classes inheriting the interface should follow.
  2. Interface provides a contract for the class implementing it. Also interfaces guarantee the inherited members are available in the inherited class.
  3. Interfaces provide runtime polymorphism and multiple inheritance.
  4. Interfaces are contract templates in which the contract members are declared.

After considering the preceding points we can provide a unique definition for interfaces.

An interface is type of class that works as a contract for the class or structure. This contract says that each method of the interface must be used in a deriving class or structure for achieving the concept of runtime polymorphism and multiple inheritance.

The following is a sample structure of an interface:

  1. interface Demo  
  2. {  
  3.     int ab  
  4.     {  
  5.         get;  
  6.         set;  
  7.     } // property Declaration  
  8.     void call(); // Method declaration  
  9.     object this[int index] // Index Declaration  
  10.     {  
  11.         get;  
  12.         set;  
  13.     }  

An interface mainly contains the following items:

  1. Methods
  2. Properties
  3. Events
  4. Indexers

We will now consider some important points about interfaces.

  1. interface Dem  
  2.     {  
  3.           void call();  
  4.          void show();  
  5.     }  
  6.     class Drived : Dem  
  7.     {  
  8.         public void call()  
  9.         {  
  10.             Console.WriteLine("You are in Call Method");  
  11.         }  
  12.         public void show()  
  13.         {  
  14.             Console.WriteLine("You are in show Method");  
  15.         }  
  16.     }  
  17.     class Demo  
  18.     {  
  19.         static void Main(string[] args)  
  20.         {  
  21.             Drived dr = new Drived();  
  22.             dr.call();  
  23.             dr.show();  
  24.             Console.ReadLine();  
  25.         }} 

Output



In the preceding example we create an interface with the name “Dem”. The Dem interface contains the two methods call and show. The Class Drived inherits the interface Dem and implement all the methods of Dem.

The following is the interface with the structure.

  1. interface Dem  
  2.     {  
  3.           void call();  
  4.          void show();  
  5.     }  
  6.     struct Str : Dem  
  7.     {  
  8.         public void call()  
  9.         {  
  10.             Console.WriteLine("Call Method of Strcut");  
  11.         }  
  12.   
  13.         public void show()  
  14.         {  
  15.             Console.WriteLine("Show Method of Struct");  
  16.         }}  
  17.     class Demo  
  18.     {  
  19.         static void Main(string[] args)  
  20.         {  
  21.             Str st = new Str();  
  22.             st.call();  
  23.             st.show();  
  24.             Console.ReadLine();  
  25.         }} 

Output



We can use an interface with a structure. In the preceding example we created an interface and structure. structure Str inherits the interface and implements the call() and show() methods of the interface.

Multilevel Inheritance using Interface

  1. interface Dem    
  2.    {    
  3.          void call();    
  4.    }       
  5.    interface Dem2 : Dem    
  6.    {    
  7.        void show();    
  8.    }       
  9.    Class  Str : Dem2    
  10.    {    
  11.        public void call()    
  12.        {    
  13.            Console.WriteLine("Call Method of Strcut");    
  14.        }      
  15.        public void show()    
  16.        {    
  17.            Console.WriteLine("Show Method of Struct");    
  18.        }}    
  19.    class Demo    
  20.    {    
  21.        static void Main(string[] args)    
  22.        {    
  23.            Str st = new Str();    
  24.            st.call();    
  25.            st.show();    
  26.            Console.ReadLine();    
  27.        }}   

Output


In the preceding example we declared two interfaces, Dem and Dem2. The interface Dem2 inherits the Interface Dem and the class str inherits the interface Dem2. The class str implements the method of both Interfaces. This is an example of Multilevel Inheritance.

Multiple Inheritance using Interface

In the C# language we cannot simply achieve the concept of multiple inheritance. But using interfaces we can achieve Multiple Inheritance.
  1. interface Dem  
  2.     {  
  3.           void call();  
  4.      }  
  5.     interface Dem2   
  6.     {  
  7.         void show();  
  8.     }  
  9.     class  Str : Dem,Dem2  
  10.     {  
  11.         public void call()  
  12.         {  
  13.             Console.WriteLine("Call Method of Strcut");  
  14.         }  
  15.         public void show()  
  16.         {  
  17.             Console.WriteLine("Show Method of Struct");  
  18.         }}  
  19.     class Demo  
  20.     {  
  21.         static void Main(string[] args)  
  22.         {  
  23.             Str st = new Str();  
  24.             st.call();  
  25.             st.show();  
  26.             Console.ReadLine();  
  27.         }} 
Output



In this example, as usual, we declare two interfaces, Dem and Dem2. The class Str inherits both of the interfaces and implements the methods of both interfaces in the class str.

Interface With Abstract Class
  1. interface Dem  
  2.     {  
  3.           void call();  
  4.      }  
  5.    abstract  class Abs : Dem  
  6.     {  
  7.        abstract public void Method();  
  8.        public void call()  
  9.        {  
  10.            Console.WriteLine("Call Method of Dem Interface");  
  11.        }  
  12.     }  
  13.     class  Str:Abs  
  14.     {  
  15.         public override void Method()  
  16.         {  
  17.             Console.WriteLine("Now I am in Str Class");  
  18.         }  
  19.         public void show()  
  20.         {  
  21.             Console.WriteLine("Show Method of Struct");  
  22.         }}  
  23.     class Demo  
  24.     {  
  25.         static void Main(string[] args)  
  26.         {  
  27.             Str st = new Str();  
  28.             st.call();  
  29.             st.show();  
  30.             st.Method();  
  31.             Console.ReadLine();  
  32.         }} 
Output



We can implement interfaces with abstract classes. An abstract class can inherit an interface. In the preceding example we declared an interface Dem and an abstract class Abs. The abstract class Abs Inherits the interface Dem.

The following is an examle of access methods of interfaces using a reference of a class:
  1. interface Intr  
  2.     {  
  3.         void Method1();  
  4.         void Method2();  
  5.     }  
  6.     class Demo2 : Intr  
  7.     {  
  8.         public void Method1()  
  9.         {  
  10.             Console.WriteLine("Method1");  
  11.         }  
  12.         public void Method2()  
  13.         {  
  14.             Console.WriteLine("Method1");  
  15.         }  
  16.     }  
  17.     class Demo  
  18.     {  
  19.         static void Main(string[] args)  
  20.         {  
  21.             Demo2 DmRef = new Demo2();  
  22.             Intr Intrf = DmRef;  
  23.             Intrf.Method1();  
  24.             Intrf.Method2();  
  25.             Console.ReadLine();  
  26.         }} 
Output



The preceding program compiles and runs successfully to produce the desired output. Inside Main() we have an interface reference Intrf of type interface Intr. We also have a reference of the class Demo2 as Dmref. The reference of object of class Demo2 is stored in Intrf and the method of class Demo2 is invoked using Intrf.

Explicit Interface Implementation


A class that implements an interface can explicitly implement a member of that interface. When a member is explicitly implemented, it cannot be accessed using a class instance, but only using an instance of the interface.
  1. interface Intr  
  2.     {  
  3.         void Method1();  
  4.         void Method2();  
  5.     }  
  6.     class Demo2 : Intr  
  7.     {  
  8.          void Intr.Method1()  
  9.         {  
  10.             Console.WriteLine("Successfully Call  Method1");  
  11.         }  
  12.          void Intr.Method2()  
  13.         {  
  14.             Console.WriteLine("Successfully Call  Method2");  
  15.         }  
  16.     }  
  17.     class Demo  
  18.     {  
  19.         static void Main(string[] args)  
  20.         {  
  21.             Demo2 DmRef = new Demo2();  
  22.             DmRef.Method1();  
  23.             DmRef.Method2();  
  24.             Console.ReadLine();  
  25.         }} 
Output



When we execute the preceding program it will throw an error. Because we cannot access the method of an explicit interface using an object of the class.

We can only access a method of an explicit interface using an instance of an interface.
  1. interface Intr  
  2.     {  
  3.         void Method1();  
  4.         void Method2();  
  5.     }  
  6.     class Demo2 : Intr  
  7.     {  
  8.          void Intr.Method1()  
  9.         {  
  10.             Console.WriteLine("Successfully Call Method1");  
  11.         }  
  12.          void Intr.Method2()  
  13.         {  
  14.             Console.WriteLine(" Successfully Call Method2");  
  15.         }  
  16.     }  
  17.     class Demo  
  18.     {  
  19.         static void Main(string[] args)  
  20.         {  
  21.             Demo2 DmRef = new Demo2();  
  22.             Intr Itr = DmRef;  
  23.             Itr.Method1();  
  24.             Itr.Method2();  
  25.             Console.ReadLine();  
  26.         }} 
Output



Another Use of Explicit Interface Implementation


An explicit interface implementation also allows the programmer to inherit two interfaces that share the same member names and give each interface member a separate implementation.

Suppose we have two interfaces and both interfaces have the same method. Then the complier will generate the error because both interfaces have the same method name due to the same name. The compiler cannot distinguish which method is of which interface. The compiler treats both methods as the same and generates an error.

This name mechanism is also known as a fully qualified name.
  1. interface Intr  
  2.     {  
  3.         void Method();          
  4.     }  
  5.     interface Intr2  
  6.     {  
  7.         void Method();  
  8.     }  
  9.     class Demo2 : Intr,Intr2  
  10.     {  
  11.        public   void Method()  
  12.         {  
  13.             Console.WriteLine(" Call Method of Intr");  
  14.         }  
  15.        public   void Method()  
  16.         {  
  17.             Console.WriteLine(" Call Method of Intr2");  
  18.         }  
  19.     }  
  20.     class Demo  
  21.     {  
  22.         static void Main(string[] args)  
  23.         {  
  24.             Demo2 DmRef = new Demo2();  
  25.             DmRef.Method();  
  26.             Console.ReadLine();  
  27.         }} 
Output



To overcome this problem we will use an explicit interface as in the following:
  1. interface Intr  
  2.     {  
  3.         void Method();          
  4.     }  
  5.     interface Intr2  
  6.     {  
  7.         void Method();  
  8.     }  
  9.     class Demo2 : Intr,Intr2  
  10.     {  
  11.           void Intr.Method()  
  12.         {  
  13.             Console.WriteLine(" Call Method of Intr");  
  14.         }  
  15.           void  Intr2.Method()  
  16.         {  
  17.             Console.WriteLine(" Call Method of Intr2");  
  18.         }  
  19.     }  
  20.     class Demo  
  21.     {  
  22.         static void Main(string[] args)  
  23.         {  
  24.             Demo2 DmRef = new Demo2();  
  25.             Intr Itr = DmRef;  
  26.             Intr2 Itr2 = DmRef;  
  27.             Itr.Method();  
  28.             Itr2.Method();  
  29.             Console.ReadLine();  
  30.         }} 
Output



This name mechanism is also known as a fully qualified name. Here Intr2.Method and Intr.Method are fully qualified names.

Use of as and is Operator in Interfaces

In the case of a interface, “as” and “is” are two important operators.

The “Is” operator is used to check the “is a type of” relationship between the parent and base class.
  1. interface Ifr  
  2.     {  
  3.         void call();  
  4.     }  
  5.     class Class1:Ifr  
  6.     {  
  7.         public void call()  
  8.         {  
  9.             Console.WriteLine("Call method of  Class1");  
  10.         }  
  11.     }  
  12.     class Class2  
  13.     {  
  14.         public void call()  
  15.         {  
  16.             Console.WriteLine("Call method of  Class2");  
  17.         }  
  18.     }  
  19.     class Demo  
  20.     {  
  21.         static void Main(string[] args)  
  22.         {  
  23.             Class1 cls1 = new Class1();  
  24.             Class2 cls2 = new Class2();  
  25.             Ifr Ifl = cls2;  
  26.             Ifl.call();  
  27.               
  28.             Console.ReadLine();  
  29.         }} 
Output



When we run the preceding program it will throw an error. Because Class2 does not inherit the interface but it wants to access the methods of the interface. Suppose we have a large collection of classes then it is difficult to identify which class inherits an interface. For this purpose we can use the “Is” operator.
  1. interface Ifr  
  2.     {  
  3.         void call();  
  4.     }  
  5.     class Class1:Ifr  
  6.     {  
  7.        public   void call()  
  8.         {  
  9.             Console.WriteLine("Call method of  Class1");  
  10.         }  
  11.     }  
  12.     class Class2  
  13.     {  
  14.         public void call()  
  15.         {  
  16.             Console.WriteLine("Call method of  Class2");  
  17.         }  
  18.     }  
  19.     class Demo  
  20.     {  
  21.         static void Main(string[] args)  
  22.         {  
  23.             Class1 cls1 = new Class1();  
  24.             Class2 cls2 = new Class2();  
  25.   
  26.             if (cls1 is Ifr)  
  27.             {  
  28.                Ifr Ifl  = cls1;  
  29.   
  30.                 Ifl.call();  
  31.             }  
  32.             Console.ReadLine();  
  33.         }} 
Output



In the preceding class the compiler will check first that class1 is a type of interface. It found that Class1 is a type of interface and therefore returns true.

As Operator

We can use the "as" operator to cast and check the types more efficiently. The "as" operator returns an object type and null if the type mismatched whereas the "is" operator returns a Boolean value.
  1. interface Ifr  
  2.     {  
  3.         void call();  
  4.     }  
  5.     class Class1:Ifr  
  6.     {  
  7.        public   void call()  
  8.         {  
  9.             Console.WriteLine("Call method of  Class1");  
  10.         }  
  11.     }  
  12.     class Demo  
  13.     {  
  14.         static void Main(string[] args)  
  15.         {  
  16.             Class1 cls1 = new Class1();  
  17.             Ifr Itr = cls1 as Ifr;  
  18.             if(Itr!=null)  
  19.             Itr.call();  
  20.             Console.ReadLine();  
  21.         }} 
Output

 
 Indexer , Property  in  Interface

Indexers are an important concept that enables us to create a class or interface. A struct is such that a user can access the class, interface or struct as an array. The type of an indexer and the type of its parameters must be at least as accessible as the indexer itself. We can also use properties in an interface as in the following:
public interface Intr
{

String Str
{
get;
set;

}
int this[int index]
{
get;
set;
}
}

class Drived : Intr
{
private int[] array = new int[10];
public string Stm;
public string Str
{
get
{
return Stm;
}
set
{
Stm = value;
}

}
public void Call()
{
Console.WriteLine(Str);
}
public int this[int index]
{
get
{

return array[index];
}
set
{
array[index] = value;
}
}
}

class Demo
{
static void Main(string[] args)
{
Drived Drv = new Drived();
Drv.Stm = "Print Value";

for (int i = 0; i < 10; i++)
{
Drv[i] = 100 + i;
}
for (int i = 0; i < 10; i++)
{
System.Console.WriteLine("Element #{0} = {1}", i, Drv[i]);
}

Drv.Call();
Console.ReadLine();
}
}
 
Output
 
 
In the preceding example we declare an indexer and a property in interface. The class Drived inherits the interface so it must implement the indexer and property.

The following are the considerations indicating the use of an interface:
  1. When we need Multiple Inheritance.
  2. To perform Runtime Polymorphism.
  3. Interfaces are useful when you cannot use class inheritance. For example, structures cannot inherit from classes, but they can implement interfaces.
  4. Where we need to provide some common method to all classes then we can use an interface that provides the reusability of code.
  5. To avoid name ambiguity between the methods of the various classes as was in the use of multiple inheritance.