C# - Interface

An interface is like a contract. In the human world, the contract between the two or more humans binds them to act as per the contract. In the same way, the interface includes the declaration of one or more functionalities. Entities that implement the interface must define functionalities declared in the interface. In C#, a class or a struct can implement one or more interfaces.

In C#, an interface can be defined using the interface keyword. Interfaces can contain methods, properties, indexers, and events as members.

Consider the following IPen interface that declares some basic functionality for a pen.

Example: An Interface
interface IPen
{
    string Color { get; set; }
    bool Open();
    bool Close();
    void Write(string text);
}

In C#, you cannot use any access modifier for any member of an interface. All the members by default are public members. If you use an access modifier in an interface then the C# compiler will give a compile-time error "The modifier 'public/private/protected' is not valid for this item". (Visual Studio will show an error immediately without compilation.)

Example: Invalid Interface with Access Modifiers
interface IPen
{
    public string Color { get; set; }  //error
    protected bool Open(); //error
    private bool Close();  //error
    protected internal void Write(string text);//error
}

An interface can only contain declarations but not implementations. The following will give a compile-time error.

Example: Invalid Interface with Implementation
interface IPen
{
    string Color { get; set; }
    bool Open();
    bool Close();
    void Write(string text){
        Console.Write(text);  //error: cannot implement method
    }
}

Implementing an Interface

A class or a Struct can implement one or more interfaces using colon (:).

Syntax: <Class or Struct Name> : <Interface Name>

For example, the following class implements IPen interface implicitly.

Example: Interface Implementation
class Cello : IPen
{
    public string Color { get; set; }
        
    private bool isOpen = false;
        
    public bool Close()
    {
        isOpen = false;
        Console.WriteLine("Cello closed for writing!");

        return isOpen;
    }

    public bool Open()
    {
        isOpen = true;
        Console.WriteLine("Cello open for writing!");
            
        return isOpen;
    }

    public void Write(string text)
    {
        //write text if open
        if(isOpen)
            Console.WriteLine("Cello: " + text);
    }
}

In the above example, the Cello class implements the IPen interface. It defines all the members of the IPen interface with public access modifier. However, other non-interface members of the class can have any access modifiers e.g. isOpen field is a private member of the Cello class.

Note:
All the members of the interface must be implemented with the public modifier in a class or struct. C# will give a compile-time error if any one of the members declared other than public access modifier.

Explicit Interface Implementation

Explicit implementation is useful when class is implementing multiple interface thereby it is more readable and eliminates the confusion. It is also useful if interfaces have same method name coincidently.

Note:
Do not use public modifier with an explicit implementation. It will give compile time error.

You can implement interface explicitly by prefixing interface name with all the members of an interface, as shown below:

Example: Explicit Implementation
class Cello : IPen
{
    string IPen.Color { get; set; }
        
    private bool isOpen = false;
        
    bool IPen.Close()
    {
        isOpen = false;
        Console.WriteLine("Cello closed for writing!");

        return isOpen;
    }

    bool IPen.Open()
    {
        isOpen = true;
        Console.WriteLine("Cello open for writing!");
            
        return isOpen;
    }

    void IPen.Write(string text)
    {
        //write text if open
        if(isOpen)
            Console.WriteLine("Cello: " + text);
    }
}

In the above example of explicit implementation, notice that it cannot use access modifier 'public' explicitly. C# will give an error if you use 'public' modifier when implementing interface explicitly.

There can be multiple classes or structs that implements the same interface. Consider the following example.

class Parker : IPen
{
    public string Color { get; set; }
        
    private bool canWrite = false;
        
    public bool Close()
    {
        canWrite = false;
        Console.WriteLine("Parker is closed now!");

        return canWrite;
    }

    public bool Open()
    {
        canWrite = true;
        Console.WriteLine("Parker is open now!");
            
        return canWrite;
    }

    public void Write(string text)
    {
        //write text if open
        if(canWrite)
            Console.WriteLine("Parker: " + text);
    }
}

As you can see, the Parker class implements the IPen class. It implements the same functionalities declared in IPen class but in a different way than Cello class. (prints different messages in Open(), Close() and Write() methods.) Thus, multiple classes or Structs can implement the same interface which performs the same action but differently.

You can now create objects of the class and assigned to a variable of interface type.

Example: Interface Type Variable
IPen pen1 = new Cello();

IPen pen2 = new Parker();

The same variable can be used to instantiate all the classes which implemented IPen interface.

IPen pen1 = new Cello();
pen1 = new Parker(); // assign Parker object to same variable

Implement Multiple Interfaces

A class or struct can implement multiple interfaces and must define all the members of all interfaces.

Example: Implement Multiple Interface
interface IBrandedPen
{
    string GetBrandName();
}

class Parker : IPen, IBrandedPen
{
    //Implement all members of IPen and IBrandedPen
}

Now, the Parker class can be instantiated and assigned to either IPen or IBrandedPen interface, as shown below.

IPen pen1 = new Parker();
pen1.Open();// valid 
pen2.GetBrandName(); //Compile-time error. Cannot call IBrandedPen method on the object of type IPen

IBrandedPen pen2 = new Parker();
pen2.GetBrandName();// valid 
pen2.Open();//Compile-time error. Cannot call IPen method on the object of type IBrandedPen

As you can see, an object only supports methods of an interface to which it assigned to, e.g. pen1 assigned to IPen so only supports methods of IPen and not of IBrandedPen.

An interface can also inherit one or more interface.

Example: Interface Inheritance
interface IPen
{
    string Color { get; set; }
    bool Open();
    bool Close();
    void Write(string text);
}

interface IBrandedPen : IPen 
{
    string GetBrandName();
}

class Parker : IBrandedPen
{
    //Implement all members of IPen and IBrandedPen
}
Points to Remember :
  1. An interface only contains declarations of method, properties, indexers, and events.
  2. An interface can be implement implicitly or explicitly by a class or struct.
  3. A class or struct which implements an interface, must use 'public' access modifier.
  4. An interface cannot include private, protected, or internal members. All the members are public by default.
  5. Do not include 'public' in an interface as all the members are public by default. C# will give compile-time error if used 'public'.
  6. Implement interface explicitly using InterfaceName. with all the members.
  7. An interface can inherit one or more interfaces.