Page 1 of 1

Interfaces

#1 rusoaica  Icon User is offline

  • They're watching you, Neo!
  • member icon

Reputation: 209
  • View blog
  • Posts: 671
  • Joined: 10-March 12

Posted 04 October 2014 - 03:10 PM

Learning C# Series

Interfaces Introduced


In this tutorial, I will try to explain the meaning, the look, the behavior and the usage of interfaces in C#.

Why is this important to learn about?

Interfaces are a rather poorly used resource of the Object Oriented Programming, even though they offer us the ability to use polymorphism at runtime level, which is one of the main characteristics of OOP.

Definitions of terms used.

Spoiler


Note: All examples were created using Visual Studio 2010, targetting the .NET Framework 4.0. We'll do our best to point out anything that might not work in older versions.

Interfaces Introduced


DESCRIPTION

What is an Interface? Well, lets think of a computer that has one connector for the serial mouse, one connector for the keyboard and one connector for the printer. Wouldn't it be great if we could use a single connector for all the three of them? So, we added the USB connector, which supports mouses, keyboards and printers, all inter-connectable at the same computer input. In this case, the USB port is the Interface between multiple devices and the multiple boards inside the computer, each driving a separate device (the mouse, the printer, etc). A more concrete definition would be the ability to use methods from separate objects (classes) through the same Interface. In fact, the very Interface looks like a class which is not YET implemented, and it is only composed out of declarations of properties, events, methods, etc. They are not implemented, because they are inherited by classes and structures which are then compelled to implement every interface member that was declared.
Interfaces are used not for implementing any sort of functionality, but to offer a way for the components that have functionalities to be changed between them. Because the functional components ALL implement the same Interface, they can be exchanged one with another without any significant changes in the codes.
Another important thing about Interfaces, is that they guarantee that the implemented methods must exist. For instance, if a class implements the Interface IDisposable, the Interface guarantees that the method member Dispose() is present and declared. So, if we want to use the class, we simply check if it is implementing IDisposable. If it does, than the code knows for sure that it can call the Dispose() method of the class.

DESIGN

Because Interfaces are someway similar to abstract classes, and because we know that they must declare their methods, properties, events, etc, the simplest way to define an Interface is like this:

interface IMyFirstInterface
{
    void SomeMethodToBeImplemented(SomeArguments);
}



Interfaces look exactly like any other class, except they use the word "interface". It is always a good practice to start the name of every interface with a capital "I", which is the prefix for "interface" in programmers language. At a first glance, one may wonder where the body of our method is (the part between curly brackets) and why it is ended in semicolon. As we said above, Interfaces ONLY contain declarations. So, we provided the signature of our method. As a side note, you will notice the absence of ANY access modifiers (protected, private, etc) and that is because they cannot be used. The default access modifier inside an Interface is public. It is also important to point out that Interfaces cannot contain fields. This means that we cannot declare variable inside interfaces. The implementation part is to be handled by the class that implements the Interface, like this:

USAGE

class MyFirstInterfaceImplementer : IMyFirstInterface
{
    static void Main()
    {
        MyFirstInterfaceImplementer MyInterfaceReference = new MyFirstInterfaceImplementer();
        MyInterfaceReference.SomeMethodToBeImplemented(SomeArguments);
    }

    void SomeMethodToBeImplemented(SomeArguments)
    {
        //here is the implemented method that had the prototype declared in the Interface
    }
}



Now, lets do the aftermath. Interfaces are inherited just as any usual class inheritance:

class MyFirstInterfaceImplementer : IMyFirstInterface



As we said before, any class that inherits an Interface, MUST implement ALL its members. That's why, we implemented the SomeMethodToBeImplemented(SomeArguments) method inside our class. When the user fails to implement all the members of an Interface or when the signatures of the methods inside the Interface and the class do not coincide, the compiler will generate an error.
Another interesting feature of the Interfaces is that they can inherit other Interfaces. So, while in C# we cannot inherit from more than one class, we can easily work around this by inheriting an Interface that inherits more than one Interface. When two Interfaces are implemented for the same class, they are separated by comma:

class Computer : IElectronics, IHardware
{
  public static void Main()
  {
    Computer refComputer = new Computer();
    IElectronics refIElectronics = refComputer;
    refIElectronics.Transistors();
    IHardware refIHardware = refComputer;
    refIHardware.MotherBoard();
  }

  void Transistors()
  {
     System.Console.WriteLine("Computers contain transistors");
  }  

  void MotherBoard()
  {
     System.Console.WriteLine("Computers contain motherboards");
  }
}

interface IElectronics
{
  void Transistors();
}

interface IHardware
{
  void MotherBoard();
}



The class Computer must implement all the methods for both interfaces. On the other hand, we can use methods from different classes through the means of a single Interface, creating an alternative to the lack of multiple class inheritance in C#:

class FirstClass : ICommonInterface
{
  public static void Main()
  {
    ICommonInterface [] refICommonInterface = {new FirstClass(), new SecondClass()} ;
    for (int i = 0; i<= 1; i++)
      ICommonInterface[i].CommonMethod();
  }

  void CommonMethod()
  {
     System.Console.WriteLine("The first implementation");
  }  
}

class SecondClass: ICommonInterface
{
  void CommonMethod()
  {
     System.Console.WriteLine("The second implementation");
  }  
}

interface ICommonInterface
{
  void CommonMethod();
}



Running the above code will print out both outputs of the methods in the separated classes, which were called through the commonly inherited Interface. In addition, Interfaces can inherit other Interfaces:

class Computer : IHardware
{
  public static void Main()
  {
    Computer refComputer = new Computer();
    IHardware refIHardware = refComputer;
    refIHardware.Transistors();
    refIHardware.MotherBoard();
  }

  void Transistors()
  {
     System.Console.WriteLine("Computers contain transistors");
  }  

  void MotherBoard()
  {
     System.Console.WriteLine("Computers contain motherboards");
  }
}

interface IElectronics
{
  void Transistors();
}

interface IHardware : IElectronics
{
  void MotherBoard();
}



Different Interfaces can contain function prototypes with the same function name. To distinguish between them, we can use fully qualified names:

class Computer : IElectronics, IHardware
{
  public static void Main()
  {
    Computer refComputer = new Computer();
    IElectronics refIElectronics = refComputer;
    refIElectronics.Components();
    IHardware refIHardware = refComputer;
    refIHardware.Components();
  }

  void IElectronics.Components()
  {
     System.Console.WriteLine("Computers contain transistors");
  }  

  void IHardware.Components()
  {
     System.Console.WriteLine("Computers contain motherboards");
  }
}

interface IElectronics
{
  void Components();
}

interface IHardware
{
  void Components();
}



For Interfaces that inherit other Interfaces, we use the fully qualified names like this:

class Computer : IHardware
{
  public static void Main()
  {
    Computer refComputer = new Computer();
    IHardware refIHardware = refComputer;
    refIHardware.Transistors();
    refIHardware.MotherBoard();
  }

  void IElectronics.Transistors()
  {
     System.Console.WriteLine("Computers contain transistors");
  }  

  void IHardware.MotherBoard()
  {
     System.Console.WriteLine("Computers contain motherboards");
  }
}

interface IElectronics
{
  void Transistors();
}

interface IHardware : IElectronics
{
  void MotherBoard();
}



BEHAVIOUR

interface IMyInterface
{
  int x;  
}



Output: error CS0525: Interfaces cannot contain fields

Interfaces cannot contain field members, such as variables.

interface IMyInterface
{
  void MyMethod()
  {
     System.Console.WriteLine("Hello World");
  }  
}



Output: error CS0531: 'IMyInterface.MyMethod()': interface members cannot have a definition

Interfaces can only declare prototypes, without implementing them.

class MyClass : IMyInterface
{
  public static void Main()
  {
    System.Console.WriteLine("Hello World");
  }
}

interface IMyInterface
{
  void MyMethod();
}



Output: error CS0535: 'MyClass' does not implement interface member 'IMyInterface.MyMethod()'

Before we can use a method declared inside an Interface, we must implement it inside the class that inherited the Interface.

class MyClass : IMyInterface
{
  public static void Main()
  {
    System.Console.WriteLine("Hello World");
  }
  void MyMethod()
  {
     System.Console.WriteLine("My method");
  }  
}

interface IMyInterface
{
  void MyMethod();
}



Output: error CS0536: 'MyClass' does not implement interface member 'IMyInterface.MyMethod()'. 'MyClass.MyMethod()' is either static, not public, or has the wrong return type.

Because we cannot specify access modifiers inside Interfaces, we must specify them when implementing the methods of the Interfaces.

class Computer : IElectronics, IHardware
{
  public static void Main()
  {
    IElectronics refIElectronics = new Computer();
    refIElectronics.Transistors();
    refIElectronics.MotherBoard();
  }

  public void Transistors()
  {
     System.Console.WriteLine("Computers contain transistors");
  }  

  public void MotherBoard()
  {
     System.Console.WriteLine("Computers contain motherboards");
  }
}

interface IElectronics
{
  void Transistors();
}

interface IHardware
{
  void MotherBoard();
}



Output: error CS0117: 'IElectronics' does not contain a definition for 'MotherBoard'

The above example will generate a compiler error because we tried to invoke MotherBoard of class Computer through refIElectronics, which contains the prototype for Transistors(), but not MotherBoard().

class Computer : IElectronics, IHardware
{
  public static void Main()
  {
    Computer refComputer = new Computer();
    IElectronics refIElectronics = refComputer;
    refIElectronics.Components();
    IHardware refIHardware = refComputer;
    refIHardware.Components();
  }

  public void IElectronics.Transistors()
  {
     System.Console.WriteLine("Computers contain transistors");
  }  

  public void IHardware.MotherBoard()
  {
     System.Console.WriteLine("Computers contain motherboards");
  }
}

interface IElectronics
{
  void Transistors();
}

interface IHardware
{
  void MotherBoard();
}



Output: error CS0106: The modifier 'public' is not valid for this item

Because we used fully qualified names and the default access modifier of an Interface method is 'public', we don't need to specify that again.

class Computer : IHardware
{
  public static void Main()
  {
    Computer refComputer = new Computer();
    IHardware refIHardware = refComputer;
    refIHardware.Transistors();
    refIHardware.MotherBoard();
  }

  void IHardware.Transistors()
  {
     System.Console.WriteLine("Computers contain transistors");
  }  

  void IHardware.MotherBoard()
  {
     System.Console.WriteLine("Computers contain motherboards");
  }
}

interface IElectronics
{
  void Transistors();
}

interface IHardware : IElectronics
{
  void MotherBoard();
}



Output: error CS0539: 'IHardware.Transistors' in explicit interface declaration is not a member of interface

The signature of method Transistors() is located in Interface IElectronics, and even though IHardware inherits IElectronics, the fully qualified name remains IElectronics.Transistors and not IHardware.Transistors.

In Conclusion
Even if Interfaces may seem odd or without any immediate functionality, they are quite useful in certain situations. Plus, once you get a grip on them, they are very simple to use.

See all the C# Learning Series tutorials here!

Happy coding! -.-

This post has been edited by Curtis Rutland: 08 October 2014 - 12:51 PM
Reason for edit:: Edited to match Learning C# template at user request


Is This A Good Question/Topic? 2
  • +

Page 1 of 1