Defining Interfaces

Define an interface with the interface keyword, a name starting with I, and members with no bodies. A class implements it by listing it after the colon, after its base class, and writing every member as public.

Journeyman · C# · OOP · Updated

After this lesson you can

  • Define an interface with methods and properties, named with a capital I
  • Implement one or more interfaces in a class, listed after its base class

Key takeaways

  • Define an interface with the interface keyword, a name that starts with a capital I, and members with no bodies.
  • A class implements interfaces by listing them after the colon, its base class first: class RidingMower : Machine, IDrivable, IBladeController.
  • The class writes each interface member as an ordinary public method or property, with no override.
  • Leave out a member and the class doesn't compile. Like an abstract class, an interface can't be created with new.

An interface is written much like a class, with three differences:

  • The keyword is interface, and by convention the name starts with a capital I: IDrivable, IBladeController. That I tells every reader at a glance that it's a contract, not a class.
  • Its members have no bodies: a method is just its signature and a semicolon, and a property just its get and set.
  • Its members don't need an access modifier: they're part of a public contract, so they're public. (Leave the modifier off, as most C# code does.)

Two interfaces

Here are the contracts for the riding mower from the last lesson:

public interface IDrivable
{
    void TurnOn();
    void Steer(string direction);
}

public interface IBladeController
{
    int BladeSpeed { get; set; }
    void TurnOn();
}

Read them as promises: anything drivable can be turned on and steered; anything with a blade controller can be turned on and has a blade speed you can read and set.

Implementing them

A class implements an interface by listing it after the colon. A base class, if there is one, comes first, then the interfaces, separated by commas:

RidingMower mower = new RidingMower("Meadow Pro", "XT1");
mower.TurnOn();
mower.Steer("left");
mower.BladeSpeed = 3;

Console.WriteLine(quot;{mower.Make} {mower.Model}: blade speed {mower.BladeSpeed}");

public interface IDrivable
{
    void TurnOn();
    void Steer(string direction);
}

public interface IBladeController
{
    int BladeSpeed { get; set; }
    void TurnOn();
}

public class Machine
{
    public string Make { get; }
    public string Model { get; }

    public Machine(string make, string model)
    {
        Make = make;
        Model = model;
    }
}

public class RidingMower : Machine, IDrivable, IBladeController
{
    public int BladeSpeed { get; set; }

    public RidingMower(string make, string model) : base(make, model)
    {
    }

    // One TurnOn keeps both contracts.
    public void TurnOn()
    {
        Console.WriteLine(quot;{Make} {Model} is running");
    }

    public void Steer(string direction)
    {
        Console.WriteLine(quot;Turning {direction}");
    }
}
Meadow Pro XT1 is running
Turning left
Meadow Pro XT1: blade speed 3

Notice:

  • RidingMower is a Machine (its one base class) and can do what IDrivable and IBladeController promise.
  • Each member is written as an ordinary public method or property. There's no override: an interface has nothing to override, so the class simply provides the member.
  • One TurnOn() keeps both contracts, which both asked for it.

Forgetting a member

Leave a member out, and the class doesn't compile. The compiler holds every class to its contracts:

Tractor tractor = new Tractor();

public interface IDrivable
{
    void TurnOn();
    void Steer(string direction);
}

public class Tractor : IDrivable
{
    public void TurnOn()
    {
        Console.WriteLine("Tractor running");
    }
}
error CS0535: 'Tractor' does not implement interface member 'IDrivable.Steer(string)'

As with an abstract class, Visual Studio can write the missing members for you: put the cursor on the red line, press Ctrl+., then Implement interface.

The base class goes first

The order after the colon matters. Put an interface before the base class, and C# complains:

RidingMower mower = new RidingMower();

public interface IDrivable
{
    void TurnOn();
}

public class Machine
{
}

public class RidingMower : IDrivable, Machine
{
    public void TurnOn()
    {
    }
}
error CS1722: Base class 'Machine' must come before any interfaces

An interface can't be created

Like an abstract class, an interface can't be created with new. There's nothing inside it to run: new IDrivable() gives the same Cannot create an instance of the abstract type or interface error you saw with BankAccount.

(Since C# 8, an interface member can carry a body, called a default interface method. It's for adding a member to an interface that many classes already implement, without breaking them. You won't need it in this course: keep your interfaces to signatures.)

Check yourself

2 questions to try on the lesson page.

So what

An interface is a few lines: a name starting with I and a list of members with no bodies. A class that lists it after its colon must write every one of them, and the compiler checks that it does.

Key terms

Cheat sheets