What is an Interface?
In the real world, an
interface
means a medium to interact with something. To be precise, it's a point where two systems, subjects, organizations meet and interact. There are few rules for the interaction to be done. Suppose you're going for an interview of Programmer Profile. The interview is only possible if the interviewer and you speak the same language. Moreover, you and the interviewer have the same skill set of programming languages to discuss upon.
Similarly, in the programming world, an
interface
means a contract to interact with multiple code modules. If aclass
wants to communicate with an interface
, it must implement it and define its members. Consider it like the interviewer's question and you need to answer it correctly, if you want the job.
The MSDN Library defines the
interface
like a pure abstract
class. An interface
contains only the signatures of methods, properties, events or indexers. It has no implementation of its own and can only be implemented by a class or a struct. Any of the two that implement the interface
must provide the definitions to members specified in the interface. It is like a contract for all the derived classes to follow.
An
interface
is declared using the keyword "interface"
. Interface members are implicitly public
andabstract
, so we cannot prefix any access modifiers to it. An interface
cannot contain fields, constant members, constructors, destructors and static
members.Why do we need an Interface?
An
interface
is not a class. It contains only method signatures. It has no implementation on its own and cannot be instantiated. Its implementation logic is provided by the classes that derived from it. An interface
is mostly considered to be a pure abstract
class. However, there is the advantage of using an interface
over anabstract
class; that is "Multiple Inheritance Support". In C#, two classes (either abstract or concrete) cannot be inherited by the same derived class. It causes ambiguity in the derived class if both have the same method signature. We can do multiple inheritance in C# using interfaces.
An
interface
plays a vital role in the Service Oriented Architecture (SOA). In WCF, we use interfaces to defineService Contracts. A class can also be used to define Service Contracts
, instead of interfaces but we cannot achieve better functionality with classes. Using interfaces, a single class can implement any number of Service Contract Interfaces. It is generally accepted as the best practice to use interfaces
as Service Contracts
, not real classes.
Most of the Design Patterns and Principles are based on
interfaces
rather than class inheritance. Some of the examples are Builder Design Pattern, Factory Pattern, Interface Segregation Principle and so on.How to Define an Interface?
Suppose we need to define a class for a
Smart Phone
. The class can have members like OS
, AppStore
and Call
. The Smartphone can be either Android based or iOS based and cannot be both. There is no common functionality between an Android and iOS Smartphone, so we don't need to provide any kind of default functionality. One approach is to make the Smartphone
class abstract
and also all its members abstract
. This approach works fine and several concrete classes like Samsung
, Apple
, HTC
can inherit from it.
Now, after a few days,
Apple
wants to add a Touch ID feature to its Smartphone. We can add TouchID
as anabstract
method in our abstract
base class SmartPhone
. But what if HTC
doesn't want that feature and neither does Samsung
? So, the TouchID
method cannot be placed inside the abstract
class SmartPhone
. An alternative is to define another abstract
class Features
and add the TouchID
method to it. This is also a bad idea since C# doesn't support inheritance of multiple classes (abstract
or concrete) into a derived class.
In this situation, an
interface
is useful and plays a vital role in solving the problem. An interface
provides only the method definitions, just like an abstract
class, but can be useful in multiple inheritances. We can make theFeatures
class an interface and add the TouchID
method to it. It provides only the method signature and whichever class inherits it can implement it in its own way. It is also completely valid for a class to inherit more than one interface in C#. Also, we can make the SmartPhone
class an interface instead of an abstract
class. It is better instead of making a pure abstract
class, we can use interfaces.
Note: The example is not a best one, but I think it gets the point across. It is just for the sake of understanding interfaces.
Let us consider the example discussed above and create a Console Application for it. Open Visual Studio and add a new console project as
"InterfaceDemo"
.
By default, it gives a class named
Program
with a Main
method in it for code execution. Let's create an abstract
class SmartPhone
and define OS
and AppStore
abstract
methods in it. We can create an abstract
class by putting the keyword "abstract
" before a class definition. If you're not familiar with abstract
classes, please go toPart-1
of this series.using System;
namespace InterfaceDemo
{
//Abstract Class SmartPhone with only abstract methods in it
abstract class SmartPhone
{
public abstract void OS();
public abstract void AppStore();
}
class Program
{
static void Main(string[] args)
{
}
}
}
Now define the concrete classes
Apple
and Samsung
that inherit from SmartPhone
and provides the definitions to the abstract
methods OS
and AppStore
.using System;
namespace InterfaceDemo
{
//Abstract Class SmartPhone with only abstract methods in it
abstract class SmartPhone
{
public abstract void OS();
public abstract void AppStore();
}
class Apple : SmartPhone
{
public override void OS()
{
//Some Implementation Here
}
public override void AppStore()
{
//Some Implementation Here
}
}
class Samsung : SmartPhone
{
public override void OS()
{
//Some Implementation Here
}
public override void AppStore()
{
//Some Implementation Here
}
}
class Program
{
static void Main(string[] args)
{
}
}
}
If we compile the code now, it works fine. Our
SmartPhone
class is implemented by two different concrete classesApple
and Samsung
and defined depending on them. Now, let us suppose Apple
wants to provide Touch ID features to its Smartphone. We can add another abstract
method TouchID
in the SmartPhone
class and letApple
inherit and implement it.using System;
namespace InterfaceDemo
{
//Abstract Class SmartPhone
abstract class SmartPhone
{
public abstract void OS();
public abstract void AppStore();
//TouchID method meant only for Apple Class
public abstract void TouchID();
}
class Apple : SmartPhone
{
public override void OS()
{
//Some Implementation Here
}
public override void AppStore()
{
//Some Implementation Here
}
//Implementing the TouchID feature
public override void TouchID()
{
//Some Implementation Here
}
}
class Samsung : SmartPhone
{
public override void OS()
{
//Some Implementation Here
}
public override void AppStore()
{
//Some Implementation Here
}
}
class Program
{
static void Main(string[] args) { }
}
}
The
Apple
class inherits the TouchID
method and provides a definition to it. Let's compile the code now and see what happens.
It throws an error saying that the
Samsung
class doesn't implement the TouchID
method. By the definition ofabstract
class, any class implements it must provide definitions to all its abstract
members. The TouchID
method is meant only for the Apple
class and the Samsung
class doesn't want to implement it. It clearly seems that our approach is wrong since the TouchID
method cannot be placed in the SmartPhone
abstract
class.
An alternative approach is to define another
abstract
class Features
and define the TouchID
method to it. This approach seems fine since whatever class inherits Features
can implement the TouchID
method.using System;
namespace InterfaceDemo
{
//Abstract Class SmartPhone
abstract class SmartPhone
{
public abstract void OS();
public abstract void AppStore();
}
//Abstract Class Features for TouchID method
abstract class Features
{
public abstract void TouchID();
}
//Apple Class inherits both SmartPhone and Features
class Apple : SmartPhone, Features
{
public override void OS()
{
//Some Implementation Here
}
public override void AppStore()
{
//Some Implementation Here
}
//Implementation of TouchID method in Apple Class
public override void TouchID()
{
//Some Implementation Here
}
}
class Samsung : SmartPhone
{
public override void OS()
{
//Some Implementation Here
}
public override void AppStore()
{
//Some Implementation Here
}
}
class Program
{
static void Main(string[] args)
{
}
}
}
Let's compile the code and see what happens.

It again throws an error saying we cannot have multiple base classes in a derived class. This is called the
Multiple Inheritance
of classes and is not allowed in C#. So, our second approach also fails to implement the TouchID
method. This is where an interface is useful and helps to solve the "Multiple Inheritance" issue in C#. We can define both the SmartPhone
and Features
as interfaces and let the classes implement them as they need to. We can also have more than one interface in a class. This is the only way to do multiple inheritance in C#.
Let's re-create the same project using
interfaces
. We can create an interface using the keyword "interface"
. It is considered a good practice to prefix "I"
before the interface name, however the point is arguable and the choice is yours.using System;
namespace InterfaceDemo
{
interface ISmartPhone //Definition of Interface
{
public void OS();
public void AppStore();
}
class Program
{
static void Main(string[] args)
{
}
}
}
We have defined the interface
ISmartPhone
with the method signature OS
and AppStore
in it. If we compile the code now, it throws an error straightaway.
It says we cannot prefix
public
modifer with method signatures. In fact, no access modifier is allowed with interface methods. Interface methods are implicitly public
in C# because an interface
is a contract meant to be used by other classes. Moreover, we must declare these methods as public
in derived classes, when we provide implementations to these methods. Also, we cannot declare these methods as static.
using System;
namespace InterfaceDemo
{
interface ISmartPhone //Definition of Interface
{
static void OS();
static void AppStore();
}
class Program
{
static void Main(string[] args)
{
}
}
}
If we compile the code, it again gives us an error.

Let's define the interface methods without any access modifier and create a concrete class
Apple
that inherits theISmartPhone
interface and provides definitions to its members.using System;
namespace InterfaceDemo
{
interface ISmartPhone
{
void OS();
void AppStore();
}
class Apple : ISmartPhone
{
//OS Method Implementation
public void OS()
{
Console.WriteLine("OS Method: The OS of this Smartphone is iOS8");
}
//AppStore Method Implementation
public void AppStore()
{
Console.WriteLine("AppStore Method: The Application Store of this Smartphone is iTunes");
}
}
class Program
{
static void Main(string[] args)
{
}
}
}
An important point that should be noted here is that whenever we implement interface members in derived classes, the access modifier must always be
public
otherwise it throws an error. If we write a protected
modifier instead of public
to the OS
method, the compiler throws an error.using System;
namespace InterfaceDemo
{
interface ISmartPhone
{
void OS();
void AppStore();
}
class Apple : ISmartPhone
{
//OS Method kept as Protected
protected void OS()
{
Console.WriteLine("OS Method: The OS of this Smartphone is iOS8");
}
//AppStore Method Implementation
public void AppStore()
{
Console.WriteLine("AppStore Method: The Application Store of this Smartphone is iTunes");
}
}
class Program
{
static void Main(string[] args) { }
}
}
In the code above, I replaced the access modifier of the
OS
method from public
to protected
. Let's compile the code and see what happens.
Yes, it throws an error saying that the
Apple
class cannot implement the OS
method because it is not public
. So, always keep your method implementations public
in derived class. We can define another concrete class Samsung
that also implements the interface ISmartPhone
and provides definitions to its members.using System;
namespace InterfaceDemo
{
interface ISmartPhone
{
void OS();
void AppStore();
}
class Apple : ISmartPhone
{
//OS Method Implementation
public void OS()
{
Console.WriteLine("OS Method: The OS of this Smartphone is iOS8");
}
//AppStore Method Implementation
public void AppStore()
{
Console.WriteLine("AppStore Method: The Application Store of this smartphone is iTunes");
}
}
class Samsung : ISmartPhone
{
//OS Method Implementation
public void OS()
{
Console.WriteLine("OS Method: The OS of this smartphone is Android");
}
//AppStore Method Implementation
public void AppStore()
{
Console.WriteLine("AppStore Method: The Application Store of this smartphone is Google Play");
}
}
class Program
{
static void Main(string[] args) { }
}
}
This code works fine since various concrete classes implement the interface and provides definitons to its members in their own way. Now if the
Apple
class wants to implement TouchID
features, it can easily be done by defining another interface IFeatures
. The Apple
class can simply inherit the interface and implement the TouchID
functionality to its class. This is the case where an interface
is useful instead of an abstract class
.using System;
namespace InterfaceDemo
{
interface ISmartPhone
{
void OS();
void AppStore();
}
//New Interface meant only for Apple Class
interface IFeatures
{
void TouchID();
}
class Apple : ISmartPhone, IFeatures
{
//OS Method Implementation
public void OS()
{
Console.WriteLine("OS Method: The OS of this smartphone is iOS8");
}
//AppStore Method Implementation
public void AppStore()
{
Console.WriteLine("AppStore Method: The Application Store of this smartphone is iTunes");
}
//TouchID Method Implementation
public void TouchID()
{
Console.WriteLine("TouchID Method: This method provides Touch/Gesture control features.");
}
}
class Samsung : ISmartPhone
{
//OS Method Implementation
public void OS()
{
Console.WriteLine("OS Method: The OS of this smartphone is Android");
}
//AppStore Method Implementation
public void AppStore()
{
Console.WriteLine("AppStore Method: The Application Store of this smartphone is Google Play");
}
}
class Program
{
static void Main(string[] args) { }
}
}
So, this way we can achieve multiple inheritance in C#. Let's create the objects of the concrete classes
Apple
andSamsung
and build the project.using System;
namespace InterfaceDemo
{
interface ISmartPhone
{
void OS();
void AppStore();
}
//New Interface meant only for Apple Class
interface IFeatures
{
void TouchID();
}
class Apple : ISmartPhone, IFeatures
{
//OS Method Implementation
public void OS()
{
Console.WriteLine("OS Method: The OS of this smartphone is iOS8");
}
//AppStore Method Implementation
public void AppStore()
{
Console.WriteLine("AppStore Method: The Application Store of this smartphone is iTunes");
}
//TouchID Method Implementation
public void TouchID()
{
Console.WriteLine("TouchID Method: This method provides Touch/Gesture Control features.");
}
}
class Samsung : ISmartPhone
{
//OS Method Implementation
public void OS()
{
Console.WriteLine("OS Method: The OS of this smartphone is Android");
}
//AppStore Method Implementation
public void AppStore()
{
Console.WriteLine("AppStore Method: The Application Store of this smartphone is Google Play");
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("//////////////////// - Interface Demo - //////////////////// \n");
Console.WriteLine("Apple SmartPhone:");
Apple apple = new Apple();
apple.OS();
apple.AppStore();
apple.TouchID();
Console.WriteLine("\n\n");
Console.WriteLine("Samsung SmartPhone:");
Samsung samsung = new Samsung();
samsung.OS();
samsung.AppStore();
Console.ReadKey();
}
}
}
If we run the code now, it works perfectly.

This is the simplest example of using
interfaces
. However, this is just a real world analogy and the approach can be debatable. My intent in this demo is to let beginners understand how to work with interfaces
. The following are the key points to be remembered when working with interfaces.Key Points
- Interface Reference Variable: An
interface
has no implementation and cannot be instantiated. However, it can be referenced to the class object that implements it. It may be noted that the object can only access the inherited members of the interface. Consider the following code:using System; namespace InterfaceDemo { interface IDriveable { void Drive(); } class Car : IDriveable { public void Drive() { Console.WriteLine("Car Class: I can drive a Car."); } } class Truck : IDriveable { public void Drive() { Console.WriteLine("Truck Class: I can drive a Truck."); } } class Program { static void Main(string[] args) { Console.WriteLine("//////////////////// - Interface Demo - //////////////////// \n"); IDriveable DriveCar = new Car(); IDriveable DriveTruck = new Truck(); DriveCar.Drive(); //Calls Car's Drive() method DriveTruck.Drive(); //Calls Truck's Drive() method Console.ReadKey(); } } }
The code shows the declaration of objects with sameinterface
reference but with different functionalities.
- Explicit Interface Implementation: When working with
interfaces
, there occurs a situation when a class implements twointerfaces
and both theinterfaces
contain a member with the same signature. When the class provides a definition to interface members, it gets confused about which member gets the definition since both have the same name. In that case, we'll use theExplicit Interface Implementation
. Suppose we have two interfacesICredtCard
andIDebitCard
and both of these interfaces have the same method signatureCardNumber
and a classCustomer
implements both of these interfaces.using System; namespace InterfaceDemo { //First Interface IDebitCard interface IDebitCard { void CardNumber(); } //Second Interface ICreditCard interface ICreditCard { void CardNumber(); } //Customer Class implementing both the Interfaces class Customer : IDebitCard, ICreditCard { } class Program { static void Main(string[] args) { } } }
There are two ways to provide method definitions tointerface
members in a derived class. If we right-click on theinterface
name, Visual Studio gives us two options to implement them.
If we implement theinterface
normally and provide a definition to theCardNumber
method, it will cause both interfaces to useCardNumber
as their implementation. We cannot provide different functionality to the interface members.
using System; namespace InterfaceDemo { //First Interface IDebitCard interface IDebitCard { void CardNumber(); } //Second Interface ICreditCard interface ICreditCard { void CardNumber(); } //Customer Class implements both the interfaces class Customer : IDebitCard, ICreditCard { public void CardNumber() { Console.WriteLine("Card Number: My Card Number is 12345678901234567890"); } } class Program { static void Main(string[] args) { } } }
If we compile the program now, the output creates more confusion since we are unable to decide which interface method was implemented since both of theinterface
s shareCardNumber
as their method. In this case, we need to tell the compiler which method is specific to which interface usingExplicit Implementation
. It can be done by prefixing theinterface
name with the method definitions in the derived class. It may be noted that explicit interface definitions are automaticallypublic
and hence no access modifier is allowed with the method definitions. We can still have the shared method definition in it.
using System; namespace InterfaceDemo { //First Interface IDebitCard interface IDebitCard { void CardNumber(); } //Second Interface ICreditCard interface ICreditCard { void CardNumber(); } //Customer Class implements both the interfaces class Customer : IDebitCard, ICreditCard { void IDebitCard.CardNumber() { Console.WriteLine("Debit Card Number: My Card Number is 12345XXXXX"); } void ICreditCard.CardNumber() { Console.WriteLine("Credit Card Number: My Card Number is 98999XXXXX"); } public void CardNumber() { Console.WriteLine("Customer ID Number: My ID Number is 54545XXXXX"); } } class Program { static void Main(string[] args) { Console.WriteLine("////////////////////- Implicit and Expliction Implementation -//////////////////// \n\n"); Customer customer = new Customer(); IDebitCard DebitCard = new Customer(); ICreditCard CreditCard = new Customer(); customer.CardNumber(); DebitCard.CardNumber(); CreditCard.CardNumber(); Console.ReadKey(); } } }
If we run the program now, we are able to differentiate members using explicit implementation.
- If you have some kind of default functionality to share across classes in the hierarchy, you can use an
abstract class
. But if you don't have any default implementation to share and just need to define contracts for derived classes to follow;interface
is the most preferred choice. - It is a standard rule when using an
interface
, be sure you have done it right the first time. Once theinterface
is implemented by derived classes, it is difficult to update or modify theinterface
since everyone else's code breaks.
0 comments:
Post a Comment