Page 1 of 1

Interfaces

#1 rusoaica  Icon User is offline

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

Reputation: 213
  • View blog
  • Posts: 675
  • 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? 4
  • +

Replies To: Interfaces

#2 xXZexxMooreXx  Icon User is offline

  • New D.I.C Head

Reputation: 3
  • View blog
  • Posts: 15
  • Joined: 28-December 14

Posted 29 December 2014 - 12:02 PM

Like delegates/events, interfaces have been another confusion topic. I'm seeing the idea of an interface concept as described, but not where it's useful. I have read where someone said that studying design patterns would help to see how they are useful.

Regardless, thanks for the tutorial.
Was This Post Helpful? 0
  • +
  • -

#3 rusoaica  Icon User is offline

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

Reputation: 213
  • View blog
  • Posts: 675
  • Joined: 10-March 12

Posted 12 February 2015 - 12:11 PM

You are welcome!
Was This Post Helpful? 0
  • +
  • -

#4 Curtis Rutland  Icon User is online

  • (╯□)╯︵ (~ .o.)~
  • member icon


Reputation: 4751
  • View blog
  • Posts: 8,462
  • Joined: 08-June 10

Posted 24 March 2015 - 12:08 PM

View PostxXZexxMooreXx, on 29 December 2014 - 02:02 PM, said:

Like delegates/events, interfaces have been another confusion topic. I'm seeing the idea of an interface concept as described, but not where it's useful. I have read where someone said that studying design patterns would help to see how they are useful.

Regardless, thanks for the tutorial.


I like to say that interfaces define a "can do/be" relationship, whereas class inheritance defines an "is a/an" relationship. A 2012 Prius "IS A" car (Car being an "abstract class", and Prius "is a" Car). Interfaces are a bit harder to describe that way, but imagine an "IGarbage" interface. What might you throw away? Paper, old food, ratty clothing...stuff that has nothing in common, except the ability to be thrown away. That's where interfaces shine. They don't describe a parent-child relationship, they basically say "any class that implements this interface can be treated in a similar way for these specific actions/properties".

Let's use a real-world, .NET Framework example. IDisposable is a common interface. Have you ever used the using construct? Not the directives at the top of the page, but something like this:

using(var sr = new StreamWriter("c:\\file.txt")) { //...


The only reason we can use StreamWriter there is because it (or one of the parent classes it derives from) implements IDisposable.

IDisposable defines just one method: Dispose. And any number of dissimilar things can be disposed of; Streams, Database connections, HTML Forms (in ASP.NET MVC Razer), unmanaged resources, etc...

You see, there's no commonality for all these things except the ability to be disposed. That's why there's not some base class that they all implement; it wouldn't make sense. But they all can be disposed of, so it does make sense to allow us to treat them the same for that purpose only.

So, the using statement takes an IDisposable. It treats the object as an IDisposable. The only method available to it when treated that way is Dispose, but that's all the statement is going to use anyway.

Let's use our own example. Let's say that you want to have some common Logging in your code. You could define an interface called ILoggable. Then write a logger class that takes ILoggable items, and writes them to a Text File. You don't need to know what is being logged; just that the class has a method that will dump its contents as a string (defined in the ILoggable interface). Who cares if it's a Person, a WebPage, a Whatever. All we need to know is that it's loggable, and this is the method that will always be there to call.

That's the true power of interfaces.
Was This Post Helpful? 1
  • +
  • -

#5 higharc91  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 6
  • Joined: 07-June 13

Posted 31 May 2015 - 07:28 AM

Thank you for your share! I have always found the concept of Interfaces to be interesting but quite difficulty to wrap my head around. This will definitely help me in my studies.
Was This Post Helpful? 1
  • +
  • -

#6 rusoaica  Icon User is offline

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

Reputation: 213
  • View blog
  • Posts: 675
  • Joined: 10-March 12

Posted 31 May 2015 - 07:49 AM

higharc91, you're welcome! :)
Was This Post Helpful? 0
  • +
  • -

#7 zinist  Icon User is offline

  • New D.I.C Head

Reputation: -1
  • View blog
  • Posts: 18
  • Joined: 25-June 15

Posted 07 July 2015 - 04:07 AM

Hi,
Thanks for the tutorial, I like the way you introduce interface and also errors along with examples.
Thanks for sharing
Was This Post Helpful? 0
  • +
  • -

#8 rusoaica  Icon User is offline

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

Reputation: 213
  • View blog
  • Posts: 675
  • Joined: 10-March 12

Posted 07 July 2015 - 06:02 AM

zinist, i'm glad it helped you!
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1