Abstract classes vs Interfaces in .NET Core

Abstract classes vs Interfaces in .NET Core

1. Abstract Class

An abstract class serves as a base class that provides shared functionality but cannot be instantiated directly. It can contain both concrete (implemented) methods and abstract methods, which must be implemented by subclasses. Abstract classes allow for default behavior while ensuring that subclasses provide specific implementations for certain methods.

When to use an abstract class:

  • Shared functionality: For providing common functionality (methods, properties, fields) that can be reused across multiple classes.
  • Partial implementation: For default code that can be shared but still requires subclasses to implement specific details.
  • Inheritance hierarchies: For cases where a class represents a specific type of another class, and subclassing is appropriate.
  • Need for fields or constructor logic: Abstract classes can have fields, properties, and constructors, which interfaces cannot.

Example:

public abstract class Vehicle

{

    public string Model { get; set; }

 

    public void StartEngine()

    {

        Console.WriteLine("Engine started...");

    }

 

    // Abstract method - subclasses must implement this

    public abstract void Drive();

}

 

public class Car : Vehicle

{

    public override void Drive()

    {

        Console.WriteLine("Driving the car...");

    }

}

 

public class Truck : Vehicle

{

    public override void Drive()

    {

        Console.WriteLine("Driving the truck...");

    }

}

2. Interface

An interface defines a contract, specifying the methods or properties that a class must implement, but it does not provide any implementation. All methods in an interface are abstract, and it cannot have fields or provide state management. Interfaces are used to define behaviors that classes must fulfill.

When to use an interface:

  • No shared implementation: For cases where only method signatures are required, and implementation is left to the implementing classes.
  • Multiple inheritance: For situations where a class should implement multiple behaviors from different interfaces, enabling flexibility.
  • Loose coupling: For designs where classes need to be decoupled and implement various sets of behaviors.

Example:

public interface IPrintable

{

    void Print();

}

 

public interface IScanable

{

    void Scan();

}

 

public class Printer : IPrintable

{

    public void Print()

    {

        Console.WriteLine("Printing the document...");

    }

}

 

public class Scanner : IScanable

{

    public void Scan()

    {

        Console.WriteLine("Scanning the document...");

    }

}

 

public class AllInOnePrinter : IPrintable, IScanable

{

    public void Print()

    {

        Console.WriteLine("Printing the document...");

    }

 

    public void Scan()

    {

        Console.WriteLine("Scanning the document...");

    }

}

Key Differences

Feature

Abstract Class

Interface

Implementation

Can provide both implemented and abstract methods.

Can only provide method signatures (no implementation).

State

Can contain fields, properties, and constructors.

Cannot contain fields or state (only method signatures).

Multiple Inheritance

A class can only inherit one abstract class.

A class can implement multiple interfaces.

Purpose

To provide shared functionality with possible abstraction.

To define a contract that classes must implement.

Use Case

When classes share behavior, or some default implementation is needed.

When enforcing that unrelated classes adhere to the same contract.

When to Choose One Over the Other:

  • Choose an abstract class if:
    • Shared behavior is needed, and subclasses need to inherit both functionality and abstract methods.
    • A clear "is-a" relationship exists between the base class and the derived classes.
    • There is a need for fields or constructor logic that can be shared across classes.
  • Choose an interface if:
    • The focus is on defining a contract that various classes can implement.
    • Multiple, unrelated classes need to implement the same set of methods.
    • Flexibility is desired, and classes should not be restricted to a single inheritance chain.

In conclusion, abstract classes are suitable when shared functionality is needed, while interfaces are best when a contract must be defined that unrelated classes can implement. Both play important roles in object-oriented design, supporting code reusability, flexibility, and maintainability.

Comments

Popular posts from this blog

Multiline to singleline IN C# - CODING

EF Core interview questions for beginners

EF Core interview questions for experienced