Menu
Coddy logo textTech

Interface vs Abstract Class

Part of the Object Oriented Programming section of Coddy's C# journey — lesson 26 of 70.

Both interfaces and abstract classes let you define contracts that other classes must follow, but they serve different purposes and have distinct capabilities.

An interface defines what a class must do, without any implementation. It's a pure contract:

public interface IFlyable
{
    void Fly();
}

public class Bird : IFlyable
{
    public void Fly()
    {
        Console.WriteLine("Flapping wings");
    }
}

An abstract class can provide both a contract and shared implementation. It's a partial blueprint:

public abstract class Vehicle
{
    public string Brand { get; set; }
    
    public void StartEngine()
    {
        Console.WriteLine("Engine started");
    }
    
    public abstract void Drive();  // Must be implemented
}

public class Car : Vehicle
{
    public override void Drive()
    {
        Console.WriteLine("Driving on roads");
    }
}

The key differences come down to inheritance rules and purpose.

A class can implement multiple interfaces but inherit from only one abstract class.

Use an interface when unrelated classes need to share behavior (like IFlyable for birds and airplanes). Use an abstract class when related classes share common code and state (like vehicles sharing an engine start mechanism).

Abstract classes can have constructors, fields, and access modifiers on members. Interfaces traditionally couldn't, though modern C# allows default implementations.

When in doubt, prefer interfaces for flexibility - you can always add an abstract class later if shared implementation becomes necessary.

challenge icon

Challenge

Easy

Let's build a media player system that demonstrates when to use interfaces versus abstract classes. You'll create a design where unrelated devices share playback behavior through an interface, while related media types share common implementation through an abstract class.

You'll organize your code across four files:

  • IPlayable.cs: Define an interface called IPlayable in the Media namespace. This interface represents the contract for anything that can play media - whether it's a phone, a TV, or a dedicated music player. It should declare a single method Play() that returns a string.
  • MediaFile.cs: Define an abstract class called MediaFile in the Media namespace. This represents the shared foundation for all media files. It should have a Title property (string) and a Duration property (int, representing seconds). Include a constructor that sets both values. Add a concrete method called GetInfo() that returns "{Title} ({Duration}s)". Also declare an abstract method GetType() that returns a string - each media type will define what kind of file it is.
  • AudioFile.cs: Define an AudioFile class in the Media namespace that inherits from MediaFile and implements IPlayable. Add an Artist property (string). The constructor should accept title, duration, and artist. Override GetType() to return "Audio". Implement Play() to return "Playing audio: {Title} by {Artist}".
  • Program.cs: In your main file, create an AudioFile using input values. Demonstrate both aspects of the class: call GetInfo() and GetType() (inherited from the abstract class), then call Play() (from the interface). Store the audio file in an IPlayable variable and call Play() again to show interface polymorphism.

You will receive three inputs:

  • Song title
  • Duration in seconds
  • Artist name

Print the output in this format:

Info: {GetInfo() result}
Type: {GetType() result}
Direct: {Play() result}
Via Interface: {Play() result from IPlayable variable}

For example, if the inputs are Bohemian Rhapsody, 354, and Queen, the output should be:

Info: Bohemian Rhapsody (354s)
Type: Audio
Direct: Playing audio: Bohemian Rhapsody by Queen
Via Interface: Playing audio: Bohemian Rhapsody by Queen

Notice how AudioFile benefits from both approaches: it inherits shared implementation (GetInfo()) from the abstract class while also fulfilling the IPlayable contract. The abstract class provides code reuse for related media types, while the interface allows any unrelated class to be "playable" without sharing an inheritance hierarchy.

Cheat sheet

An interface defines a contract that classes must follow, without any implementation:

public interface IFlyable
{
    void Fly();
}

public class Bird : IFlyable
{
    public void Fly()
    {
        Console.WriteLine("Flapping wings");
    }
}

An abstract class provides both a contract and shared implementation:

public abstract class Vehicle
{
    public string Brand { get; set; }
    
    public void StartEngine()
    {
        Console.WriteLine("Engine started");
    }
    
    public abstract void Drive();  // Must be implemented
}

public class Car : Vehicle
{
    public override void Drive()
    {
        Console.WriteLine("Driving on roads");
    }
}

Key differences:

  • A class can implement multiple interfaces but inherit from only one abstract class
  • Use interfaces when unrelated classes need to share behavior
  • Use abstract classes when related classes share common code and state
  • Abstract classes can have constructors, fields, and access modifiers
  • Prefer interfaces for flexibility

Try it yourself

using System;
using Media;

class Program
{
    public static void Main(string[] args)
    {
        // Read input values
        string title = Console.ReadLine();
        int duration = Convert.ToInt32(Console.ReadLine());
        string artist = Console.ReadLine();
        
        // TODO: Create an AudioFile using the input values
        
        // TODO: Print Info: followed by the result of GetInfo()
        
        // TODO: Print Type: followed by the result of GetType()
        
        // TODO: Print Direct: followed by the result of Play()
        
        // TODO: Store the audio file in an IPlayable variable
        
        // TODO: Print Via Interface: followed by the result of Play() from the IPlayable variable
    }
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming