C# Interfaces Tutorial

In this tutorial we learn about interfaces that have no member implementation, forcing developers to follow a specific design and allowing us to build loosely coupled applications. We also cover how to implement multiple interfaces.

Here's a table of contents of what you'll learn in this lesson:
(click on a link to skip to its section)

Let's jump right in.

What is an interface

Interfaces are similar to abstract classes in the sense that their members are not implemented.

If you remember from our tutorial on composition , we spoke about favoring a Has-A relationship over an Is-A relationship. To recap quickly:

  • Inheritance can be abused, which may lead to a large, fragile, hierarchy of classes.
  • Inheritance makes our classes tightly coupled and dependent on each other. We want them to be as loosely coupled as possible.

An interface allows us to have Has-A relationships between classes. Instead of defining a class for each relationship, we define interfaces.

While interfaces have nothing to do with inheritance, they do allow for polymorphic behavior in a similar way.

Syntax:
interface IIdentifier
{
	funcType funcIdentifier();
}

class ClassIdentifier : IIdentifier
{
	access funcType funcIdentifier();
}

The identifier is prefixed with the capital letter I, this is a recommended naming convention for interfaces. Interface members also do not specify access modifiers, they are automatically public.

The method of the interface doesn’t have a body and the statement is terminated with a semicolon.

The statement reads: ClassIdentifier implements IIdentifier

Example:
using System;

namespace Interfaces
{
	class Program
	{
		static void Main(string[] args)
		{
			Sparrow sparrow = new Sparrow();
			sparrow.Fly(10f);

			Plane plane = new Plane();
			plane.Fly(100f);

			Console.ReadLine();
		}
	}

	public interface IFlyable
	{
		void Fly(float speed);
	}

	public class Sparrow : IFlyable
	{
		public void Fly(float speed)
		{
			Console.WriteLine("Sparrow, flying at a speed of {0}", speed);
		}
	}

	public class Plane : IFlyable
	{
		public void Fly(float speed)
		{
			Console.WriteLine("Plane, flying at a speed of {0}", speed);
		}
	}
}

In the example above, both our Duck and Plane classes implement the interface IFlyable, because both of them can fly.

They fly in different ways and at dramatically different speeds, so we allow each class to implement the Fly() function in its own way.

How to implement multiple interfaces

One benefit of interfaces is that we can implement more than just one.

Interfaces aren’t used for multiple inheritance, it’s just a benefit when using an interface.

Syntax:
interface IInterface1
{
	funcType funcIdentifier();
}
interface IInterface2
{
	funcType funcIdentifier();
}

class ClassIdentifier : IInterface1, IInterface2
{
	access funcType funcIdentifier();
}

Multiple implementations are separated by a comma.

Example:
using System;

namespace Interfaces
{
	class Program
	{
		static void Main(string[] args)
		{
			Sparrow sparrow = new Sparrow();
			sparrow.Fly(10f);
			sparrow.Hop(2);

			Plane plane = new Plane();
			plane.Fly(100f);

			Console.ReadLine();
		}
	}

	public interface IFlyable
	{
		void Fly(float speed);
	}

	public interface IHoppable
	{
		void Hop(int hps);
	}

	public class Sparrow : IFlyable, IHoppable
	{
		public void Fly(float speed)
		{
			Console.WriteLine("Sparrow, flying at a speed of {0}", speed);
		}
		public void Hop(int hps)
		{
			Console.WriteLine("Sparrow, hopping at {0} hops per second", hps);
		}
	}

	public class Plane : IFlyable
	{
		public void Fly(float speed)
		{
			Console.WriteLine("Plane, flying at a speed of {0}", speed);
		}
	}
}

In the example above, we create another interface called IHoppable. Because a sparrow can both fly and hop around, it can implement both interfaces.

Everything is loosely coupled, so if we wanted to add a Bunny class, all we need to do is implement the IHoppable interface.

Summary: Points to remember

  • Interfaces are, essentially, classes that have no implementation on their members.
  • Interfaces allow us to build loosely coupled applications that are not dependent on a fragile inheritance hierarchy.
  • An extra feature of using interfaces is that we can implement multiple interfaces on a single class.