CodeGym /Courses /C# SELF /The Concept of Interface and Its Syntax

The Concept of Interface and Its Syntax

C# SELF
Level 23 , Lesson 0
Available

1. What is an interface?

If an abstract class is a kind of "semi-finished" template with partial implementation, then a interface is just a list of requirements: what a certain being (class) must be able to do so that it can be used in some abstract context.

In programming, an interface is like a "contract" or "list of requirements" for an object's behavior. It describes a set of public methods, properties, indexers, and events that a class implementing this interface must provide. The interface says: "If you want to be called, for example, IDriveable, then please provide the methods Drive() and Stop()."

You can imagine an interface as a List of Employee Requirements: for example, if you want to hire "Cooks", the interface will say: "Must be able to cook, serve dishes, wash hands." How exactly the cook does these things is up to them. The main thing is that from the outside, they work according to the contract.

Important: the interface only describes what the class should provide, not how it's done.

In OOP terms, briefly

  • Interface describes the external "look" (API) of an object: what actions it allows you to perform.
  • Contains no state (no fields). In the classic sense, interfaces also don't contain implementation, but in modern C# there are exceptions (like default methods), which we'll talk about later.
  • One class can implement as many interfaces as it wants (unlike class inheritance!).

Real-life analogy

USB port — everyone knows you can plug in a mouse, keyboard, flash drive, headphones, even a coffee maker (yep, that's a thing!). What's inside the "mouse" doesn't matter, as long as it has a USB plug and the device supports the right protocol. That's what an interface is!

Why do we need interfaces?

  • Loosens coupling. Code works with the interface, not a specific class. We "program to the interface".
  • Lets you implement multiple inheritance of behavior: a class can implement several interfaces.
  • Standardization: you can make universal mechanisms: for example, all objects that can be compared implement the IComparable interface.
  • Testability: it's easy to swap out a real implementation for a "stub" in tests.
  • Plugin-friendliness: you can add new "modules" without changing existing code.

2. Interface declaration syntax

Now — to the code! In C#, you declare an interface using the interface keyword, and by convention, interface names start with I :


// Interface declaration
public interface IPrintable
{
    // Abstract method — contract
    void Print();

    // You can also declare properties
    string Name { get; set; }
}

Remember: interface methods and properties do NOT have implementations (no method body, just the signature — just like abstract methods).

Key features of an interface

  • You can't declare fields (member variables) inside an interface.
  • All methods, properties, events, and indexers are by default public (and must be public in the implementation).
  • An interface can't have constructors (since it has no state).
  • An interface doesn't care if the implementing class is abstract or concrete.

Interface in action

Let's integrate an interface into our learning app. Let's say we now have a "printable" interface (IPrintable), which is implemented by the Report class and, for example, a new class Invoice.

public interface IPrintable
{
    void Print();
    string Name { get; set; }
}

Now let's define a class that implements this interface:

public class Report : IPrintable
{
    public string Name { get; set; }

    public Report(string name)
    {
        Name = name;
    }

    // Implementation of the interface method
    public void Print()
    {
        Console.WriteLine($"Printing report: {Name}");
    }
}

And now — a totally different class, but with the same interface:

public class Invoice : IPrintable
{
    public string Name { get; set; }

    public Invoice(string name)
    {
        Name = name;
    }

    public void Print()
    {
        Console.WriteLine($"Printing invoice: {Name}");
    }
}

Now we can write a method that works with any printable entity:

public static void PrintAnything(IPrintable printable)
{
    printable.Print(); // That's it! Doesn't matter if it's a report or an invoice — the main thing is it can print.
}

And here's an example of using it:

var report = new Report("Monthly Report");
var invoice = new Invoice("Invoice #12345");

PrintAnything(report);  // Printing report: Monthly Report
PrintAnything(invoice); // Printing invoice: Invoice #12345

That's how interfaces let you write universal, extensible, and clean code.

3. Implementing interfaces

Connecting an interface to a class

An interface is implemented by a class using a colon (yep, just like inheritance):

public class Ticket : IPrintable
{
    public string Name { get; set; }
    public void Print()
    {
        Console.WriteLine($"Printing ticket: {Name}");
    }
}

Important: the class must implement all members of the interface. The implemented members must be public.

If you skip even one member:

public class BrokenTicket : IPrintable
{
    // Implementation of Print() is missing
    public string Name { get; set; }
}
// Compilation error: 'BrokenTicket' does not implement interface member 'IPrintable.Print()'

Multiple interfaces

A class can implement several interfaces, separated by commas:

public interface IStorable
{
    void Store();
}

public class MultiPurposeDoc : IPrintable, IStorable
{
    public string Name { get; set; }
    public void Print()
    {
        Console.WriteLine("Printing document");
    }

    public void Store()
    {
        Console.WriteLine("Saving document");
    }
}

4. Why do we need interfaces?

Maybe right now you're thinking: "Okay, I get the syntax. But why do I need all this in real life, except to make my life harder in this course?" Let me reassure you! Interfaces are one of the most commonly used tools in professional development.

Separation of responsibility and loose coupling (Decoupling / Loose Coupling):

  • Imagine you're building a music player. It doesn't care where the music comes from — a local file, the internet, or a CD. It only cares that the music source can provide an audio stream.
  • You can define an interface IAudioSource with a method GetAudioStream().
  • Then you'll have classes like FileAudioSource, InternetAudioSource, CDAudioSource that implement this interface.
  • Your player will work with IAudioSource without knowing the specific type. If tomorrow you get a new source, like BluetoothAudioSource, you don't have to change the player code! Just create a new class that implements IAudioSource. This makes your system way more flexible and easy to extend. That's loose coupling — components depend on abstractions (interfaces), not concrete implementations.

Polymorphism and uniform handling:

Like we saw in the PrintAnything example, you can have a bunch of objects of different types, but they're united by common behavior described in the interface. You can call the same method (Print()) on all these objects, without knowing who exactly you're dealing with — a report, an invoice, or a ticket. This lets you write really concise and universal code.

Testing (Unit Testing):

This is probably one of the most important uses of interfaces. When you're testing some component of your system, it often needs other components to work (for example, a class that saves data might depend on a class that works with the database).

Instead of passing in the real DatabaseSaver class (which needs a real database to test!), you can pass in a "fake" (or "mocked") object that just implements the IDataSaver interface. This "mocked" object will just imitate saving behavior, without touching a real database. This lets you test components in isolation, quickly, and without external dependencies.

API and framework development:

When you're building a library or framework, you want to give developers "extension points". Interfaces are perfect for this. You can say: "If you want your component to work with my system, just implement this interface." The .NET standard libraries are full of interfaces (like IEnumerable<T>, IDisposable, IComparable<T>) — they define contracts for the most common scenarios.

Direct programming to interfaces (Programming to an Interface):

Experienced devs often say: "Program to an interface, not an implementation." That means when you define a variable type or method parameter, instead of a specific class (Car), it's better to use an interface (IDriveable). This makes your code more flexible and less dependent on implementation details, letting you easily swap one implementation for another.

5. Typical mistakes when working with interfaces

Mistake #1: trying to create an instance of an interface.
You can write Cat murzik = new Cat("Murzik", 3); because Cat is a concrete class. But you can't write ITalkable talker = new ITalkable();. An interface is just a contract, a template. It doesn't have an implementation and can't be created directly. It's like a blueprint, not a finished house.

Mistake #2: forgot to implement all interface members.
If you say your class implements an interface, like IMyInterface, then it must implement all its methods. Even one missing method will cause a compile error: MyClass does not implement IMyInterface.TheMissingMethod().

Mistake #3: wrong access modifiers in implementation.
Interface methods are implicitly public, and in the implementation they must also be public. If you try to make a method private or protected, the compiler will throw an error. Promised — implement it openly.

Mistake #4: trying to add fields or constructors to an interface.
Interfaces describe behavior, not state. So you can't add fields or constructors to them. If you try — you'll get a compile error. Only properties are allowed, and even then — just as getter/setter descriptions.

Mistake #5: confusing override and interface implementation.
The override keyword is used to override base class methods. But when implementing an interface, you don't need it — you just write a public method with the right signature. It's an important nuance that's easy to miss.

2
Task
C# SELF, level 23, lesson 0
Locked
Declaring a simple interface and its implementation
Declaring a simple interface and its implementation
2
Task
C# SELF, level 23, lesson 0
Locked
Several classes with a common interface
Several classes with a common interface
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION