<style> .reveal-up, .reveal-left, .reveal-right, .reveal-stagger > * { opacity: 1 !important; transform: none !important; } </style>
  1. Learn
  2. C#
  3. Object-oriented programming
All lessons in this course

Lesson 25 of 60 16 minIntermediate

Interfaces

Contracts that any class can sign: define interfaces, implement several at once, program against them, and choose between interfaces and abstract classes.

A Beam, a Bolt and a Drawing have nothing in common as things, so they shouldn’t share a base class. Yet all three can be exported to IFC. An interface describes a capability (“can be exported”) that any class can promise to provide, regardless of its family.

IExportable.cs
public interface IExportable          // by convention, names start with I{    string ToIfc();                    // a promise: no body, no access modifier needed} public class Bolt : IExportable        // "Bolt implements IExportable"{    public string Grade { get; init; } = "8.8";    public string ToIfc() => $"IFCMECHANICALFASTENER('{Grade}')";} public class Beam : StructuralMember, IExportable   // base class first, then interfaces{    public string ToIfc() => $"IFCBEAM('{Mark}')";}
Interactive

Interfaces are capabilities

Pick an interface. Every class that implements it lights up, even classes that share no base class. Code written against the interface works with all of them.

interfaceIExportable { string ToIfc(); }
class Beam
: StructuralMember, IWeighable, IExportable, IPrintable
WeighableExportablePrintable
✓ can be used as IExportable
class Bolt
: IWeighable, IExportable
WeighableExportablePrintable
✓ can be used as IExportable
class Report
: IPrintable
WeighableExportablePrintable
✗ not IExportable
class Drawing
: Document, IExportable, IPrintable
WeighableExportablePrintable
✓ can be used as IExportable
// works for EVERY class above that is IExportable
static void Process(IExportable item) { File.AppendAllText("model.ifc", item.ToIfc()); }
// fits: Beam, Bolt, Drawing

Programming to the interface

Export.cs
static void ExportAll(IEnumerable<IExportable> items){    foreach (IExportable item in items)        Console.WriteLine(item.ToIfc());} var model = new List<IExportable>{    new Beam { Mark = "B1" },    new Bolt { Grade = "10.9" }};ExportAll(model);
Output
IFCBEAM('B1')
IFCMECHANICALFASTENER('10.9')

ExportAll doesn’t know or care about beams or bolts. It only needs “something that can ToIfc()”. New exportable classes will work with it without changing a line. This is how large applications stay flexible.

Several interfaces at once

Many.cs
public interface IWeighable { double WeightKg { get; } }public interface IPrintable { void Print(); } public class Beam : StructuralMember, IExportable, IWeighable, IPrintable{    public double WeightKg => Length * 42.2;    public string ToIfc() => $"IFCBEAM('{Mark}')";    public void Print() => Console.WriteLine($"{Mark}: {WeightKg:F1} kg");}

A class can inherit from only one class, but can implement any number of interfaces. This is how C# avoids the problems of multiple inheritance while still allowing an object to play many roles.

Interfaces you already use

InterfaceCapabilityEnables
IEnumerable<T>can be iteratedforeach, LINQ
IComparable<T>can be orderedList.Sort(), Array.Sort()
IDisposableholds resources to releaseusing statements
IEquatable<T>typed equalityfast Equals, dictionary keys
Sort.cs
public class Beam : IComparable<Beam>{    public string Mark { get; init; } = "";    public double Length { get; init; }    public int CompareTo(Beam? other) => Length.CompareTo(other?.Length ?? 0);} var beams = new List<Beam> { new() { Mark = "B1", Length = 7 }, new() { Mark = "B2", Length = 4 } };beams.Sort();                                   // uses CompareToConsole.WriteLine(string.Join(", ", beams.Select(b => b.Mark)));
Output
B2, B1

Interface or abstract class?

InterfaceAbstract class
Describesa capability (“can do”)a family (“is a”)
A class can havemanyone
Fields / statenoyes
Constructorsnoyes
Shared codelimited (default methods, C# 8+)yes, normal methods
Use whenunrelated classes share a behaviour; for testability and plug-insclosely related classes share code and data
Quick check

How many interfaces can a C# class implement?

Quick check

What does IExportable x = new Bolt(); require?

Practice

Define an interface IDiscountable with a method decimal ApplyDiscount(decimal price). Implement it in StudentDiscount (20% off) and FestivalDiscount (₹500 off, never below 0). Write a method that takes an IDiscountable and prints the final price of ₹2000.

Show the solution
Solution.cs
public interface IDiscountable{    decimal ApplyDiscount(decimal price);} public class StudentDiscount : IDiscountable{    public decimal ApplyDiscount(decimal price) => price * 0.8m;} public class FestivalDiscount : IDiscountable{    public decimal ApplyDiscount(decimal price) => Math.Max(0, price - 500);} static void Show(IDiscountable d) =>    Console.WriteLine($"{d.GetType().Name}: {d.ApplyDiscount(2000m)}"); Show(new StudentDiscount());Show(new FestivalDiscount());
Output
StudentDiscount: 1600.0
FestivalDiscount: 1500

Remember

  • An interface is a contract of members a class promises to implement.
  • One base class, many interfaces: class Beam : Member, IExportable, IPrintable.
  • Write methods that accept interfaces so any implementing class works.
  • Interface = capability across families; abstract class = shared code within a family.
0 of 60 lessons completed