← Back to Articles         
Abstraction

Abstraction

Published on 12 Oct 2026     15 min read OOPs
Abstraction

Section 3: Abstraction, Abstract Classes & Interfaces | 10 Important Questions | C# / .NET

1. 🔴 What is abstraction, and how is it implemented in C#?

What is abstraction?

Abstraction is one of the four main pillars of Object-Oriented Programming (OOP).

It is the process of hiding internal implementation details and exposing only essential functionality to the user.

In C#, abstraction is primarily implemented using:

  1. Abstract classes – Define common functionality and abstract members that derived classes must implement.

  2. Interfaces – Define contracts that implementing classes must follow.

C# example

Consider a payment system supporting UPI and credit card payments.

public interface IPayment
{
    void Pay(decimal amount);
}

public class UpiPayment : IPayment
{
    public void Pay(decimal amount)
    {
        Console.WriteLine($"UPI Payment: {amount}");
    }
}

public class CardPayment : IPayment
{
    public void Pay(decimal amount)
    {
        Console.WriteLine($"Card Payment: {amount}");
    }
}

Usage:

IPayment payment = new UpiPayment();
payment.Pay(1000);

payment = new CardPayment();
payment.Pay(2000);

Output:

UPI Payment: 1000
Card Payment: 2000

Code explanation

  • IPayment defines the Pay() contract.

  • UpiPayment implements UPI payment processing.

  • CardPayment implements credit card payment processing.

  • The calling code interacts with the IPayment interface without depending on a specific implementation.

Real-time scenario

In ASP.NET Core Web API, controllers commonly depend on service interfaces rather than concrete service classes.

EmployeeController
        |
        v
IEmployeeService
        |
        v
EmployeeService
        |
        v
IEmployeeRepository
        |
        v
EmployeeRepository
        |
        v
SQL Server

The controller depends on the service contract and does not need to know how the service accesses the database.

Interview answer

Abstraction is the process of hiding implementation details and exposing only essential functionality. In C#, it is implemented using abstract classes and interfaces. It reduces coupling, improves maintainability, and allows implementations to change without affecting dependent code.

 

2. 🔴 What is an abstract class, and when should you use it?

What is an abstract class?

An abstract class is a class declared using the abstract keyword that cannot be instantiated directly.

It is designed to serve as a base class for other classes.

An abstract class can contain:

  • Abstract methods without implementations.

  • Concrete methods with implementations.

  • Fields and properties.

  • Constructors.

  • Virtual methods that derived classes can override.

C# example

public abstract class Employee
{
    public string Name { get; set; } = "";

    public abstract decimal CalculateBonus();

    public void Display()
    {
        Console.WriteLine($"Employee: {Name}");
    }
}

public class Manager : Employee
{
    public override decimal CalculateBonus()
    {
        return 20000;
    }
}

public class Developer : Employee
{
    public override decimal CalculateBonus()
    {
        return 10000;
    }
}

Usage:

Employee emp1 = new Manager { Name = "John" };
Employee emp2 = new Developer { Name = "David" };

emp1.Display();
Console.WriteLine(emp1.CalculateBonus());

emp2.Display();
Console.WriteLine(emp2.CalculateBonus());

Output:

Employee: John
20000
Employee: David
10000

Code explanation

  • Employee is an abstract base class.

  • CalculateBonus() is an abstract method, so concrete derived classes must implement it.

  • Display() contains shared functionality.

  • Manager and Developer inherit the common behavior.

When should you use an abstract class?

Use an abstract class when:

  1. Multiple related classes share common functionality.

  2. You need common fields, constructors, or state.

  3. You want to enforce certain methods in derived classes.

  4. You need to provide default implementations that subclasses can reuse.

Real-time scenario

In a banking application:

           BankAccount
          (Abstract Class)
                 |
          +------+------+
          |             |
     SavingsAccount  CurrentAccount
          |             |
     CalculateInterest()

Both account types can share account number, balance, deposit, and withdrawal functionality while implementing different account-specific rules.

Interview answer

An abstract class is a class that cannot be instantiated directly and is intended to be inherited. It can contain abstract methods, implemented methods, fields, properties, and constructors. We use abstract classes when related classes need shared functionality along with mandatory methods that derived classes must implement.

 

3. 🔴 What is an interface, and why is it used?

What is an interface?

An interface defines a contract that specifies the functionality an implementing class must provide.

Interfaces are declared using the interface keyword.

They are commonly used to achieve abstraction, loose coupling, dependency injection, and polymorphism.

C# example

public interface INotificationService
{
    void Send(string message);
}

public class EmailNotification : INotificationService
{
    public void Send(string message)
    {
        Console.WriteLine($"Email: {message}");
    }
}

public class SmsNotification : INotificationService
{
    public void Send(string message)
    {
        Console.WriteLine($"SMS: {message}");
    }
}

Usage:

INotificationService service = new EmailNotification();

service.Send("Payment Successful");

service = new SmsNotification();

service.Send("Payment Successful");

Output:

Email: Payment Successful
SMS: Payment Successful

Why are interfaces used?

Benefit

Explanation

Abstraction

Exposes functionality without requiring callers to know implementation details

Loose coupling

Classes depend on contracts instead of concrete implementations

Dependency injection

Allows implementations to be injected at runtime

Testability

Makes it easier to substitute test doubles

Polymorphism

Multiple classes can implement the same contract

Extensibility

New implementations can be added without changing existing consumers

Real-time ASP.NET Core example

Interface:

public interface IEmployeeService
{
    string GetEmployeeName(int id);
}

Implementation:

public class EmployeeService : IEmployeeService
{
    public string GetEmployeeName(int id)
    {
        return "John";
    }
}

Dependency injection registration:

builder.Services.AddScoped<IEmployeeService, EmployeeService>();

Controller:

[ApiController]
[Route("api/employees")]
public class EmployeeController : ControllerBase
{
    private readonly IEmployeeService _service;

    public EmployeeController(IEmployeeService service)
    {
        _service = service;
    }

    [HttpGet("{id}")]
    public IActionResult Get(int id)
    {
        return Ok(_service.GetEmployeeName(id));
    }
}

Code explanation

  1. IEmployeeService defines the contract.

  2. EmployeeService provides the implementation.

  3. AddScoped() registers the implementation with the DI container.

  4. ASP.NET Core injects the service into the controller.

  5. The controller does not create EmployeeService directly.

Interview answer

An interface defines a contract that implementing classes must follow. Interfaces are used to achieve abstraction, loose coupling, dependency injection, polymorphism, and testability. In ASP.NET Core, interfaces are commonly used between controllers, services, and repositories.

 

4. 🔴 What is the difference between an abstract class and an interface?

Comparison table

Feature

Abstract class

Interface

Keyword

abstract class

interface

Main purpose

Shared base functionality

Define a contract

Object creation

Cannot instantiate directly

Cannot instantiate directly

Constructors

Yes

No instance constructors

Instance fields

Yes

No

Properties

Yes

Yes

Abstract methods

Yes

Yes, through members without bodies

Implemented methods

Yes

Yes, with default implementations

Access modifiers

Supported

Supported, subject to interface rules

Multiple inheritance

Only one direct base class

Multiple interfaces allowed

State management

Can maintain instance state

Cannot maintain instance fields

Best use

Related classes sharing code

Unrelated classes sharing a capability

C# example: Abstract class

public abstract class Vehicle
{
    public string Brand { get; set; } = "";

    public void Start()
    {
        Console.WriteLine("Vehicle started");
    }

    public abstract void Drive();
}

public class Car : Vehicle
{
    public override void Drive()
    {
        Console.WriteLine("Car is driving");
    }
}

Here, Vehicle provides common state and functionality.

C# example: Interface

public interface IPrintable
{
    void Print();
}

public class Invoice : IPrintable
{
    public void Print()
    {
        Console.WriteLine("Printing invoice");
    }
}

public class Report : IPrintable
{
    public void Print()
    {
        Console.WriteLine("Printing report");
    }
}

Here, unrelated classes implement the same capability.

When should you choose each?

Choose an abstract class when:

  • Classes share common fields or implementation.

  • There is a strong inheritance relationship.

  • You need constructors or shared state.

Choose an interface when:

  • You need a contract between components.

  • Multiple unrelated classes must provide the same functionality.

  • You need dependency injection and easy substitution.

  • A class must support multiple capabilities.

Interview answer

An abstract class provides a common base with shared state and functionality, while an interface primarily defines a contract. A class can inherit only one base class but implement multiple interfaces. Abstract classes are useful for related classes with shared behavior, while interfaces are preferred for loose coupling, dependency injection, and extensibility.

 

5. 🔴 Can an abstract class contain constructors, fields, properties, and implemented methods?

Yes. An abstract class can contain constructors, fields, properties, abstract methods, and implemented methods.

Although an abstract class cannot be instantiated directly, its constructor executes when a derived class is instantiated.

C# example

public abstract class Employee
{
    // Field
    protected decimal _salary;

    // Property
    public string Name { get; set; }

    // Constructor
    protected Employee(string name, decimal salary)
    {
        Name = name;
        _salary = salary;

        Console.WriteLine("Base constructor called");
    }

    // Implemented method
    public void Display()
    {
        Console.WriteLine($"{Name} - {_salary}");
    }

    // Abstract method
    public abstract decimal CalculateBonus();
}

public class Manager : Employee
{
    public Manager(string name, decimal salary)
        : base(name, salary)
    {
        Console.WriteLine("Derived constructor called");
    }

    public override decimal CalculateBonus()
    {
        return _salary * 0.20m;
    }
}

Usage:

Manager manager = new Manager("John", 100000);

manager.Display();

Console.WriteLine(manager.CalculateBonus());

Output:

Base constructor called
Derived constructor called
John - 100000
20000.00

Important points

  • Abstract classes can have constructors.

  • The base constructor executes before the derived constructor body.

  • Abstract classes can contain private, protected, and public members.

  • Abstract methods have no body and require implementation by concrete derived classes.

  • Implemented methods can be inherited and reused.

Interview answer

Yes, an abstract class can contain constructors, fields, properties, abstract methods, and implemented methods. Its constructor is executed when a derived class is instantiated. Abstract classes are useful when multiple derived classes need common state and functionality.

 

6. 🔴 Can a class implement multiple interfaces and inherit multiple classes?

Explanation

C# does not support multiple class inheritance, but it supports implementing multiple interfaces.

A class can inherit from only one base class while implementing any number of interfaces.

Multiple class inheritance – Not allowed

public class Father { }

public class Mother { }

// Compilation error
public class Child : Father, Mother
{
}

C# does not allow a class to inherit directly from two classes.

Multiple interface implementation – Allowed

public interface IPrintable
{
    void Print();
}

public interface ISavable
{
    void Save();
}

public class Document : IPrintable, ISavable
{
    public void Print()
    {
        Console.WriteLine("Printing document");
    }

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

Usage:

Document doc = new Document();

doc.Print();
doc.Save();

One base class + multiple interfaces

public class BaseDocument
{
    public void Open()
    {
        Console.WriteLine("Opening document");
    }
}

public class PdfDocument
    : BaseDocument, IPrintable, ISavable
{
    public void Print()
    {
        Console.WriteLine("Printing PDF");
    }

    public void Save()
    {
        Console.WriteLine("Saving PDF");
    }
}

Why doesn't C# support multiple class inheritance?

One reason is to avoid ambiguity when multiple base classes define conflicting implementations, commonly illustrated by the diamond problem.

C# instead supports multiple interfaces, with explicit rules for resolving interface member implementations.

Interview answer

C# supports single class inheritance and multiple interface implementation. A class can inherit from only one base class but implement multiple interfaces. This allows a class to support multiple capabilities without the complications of multiple class inheritance.

 

7. 🟡 Can interfaces contain method implementations in modern C#?

Yes. Starting with C# 8.0, interfaces can contain default method implementations.

This feature is called Default Interface Methods (DIM).

C# example

public interface ILogger
{
    void Log(string message);

    // Default implementation
    void LogError(string message)
    {
        Console.WriteLine($"ERROR: {message}");
    }
}

public class FileLogger : ILogger
{
    public void Log(string message)
    {
        Console.WriteLine($"FILE: {message}");
    }
}

Usage:

ILogger logger = new FileLogger();

logger.Log("Application started");

logger.LogError("Database connection failed");

Output:

FILE: Application started
ERROR: Database connection failed

Important points

  • Default interface methods were introduced in C# 8.0.

  • Interfaces can provide implementations for certain members.

  • Implementing classes do not need to override default methods.

  • Default interface members are not automatically exposed as public members of the implementing class.

For example:

FileLogger logger = new FileLogger();

// Not available directly on FileLogger
// logger.LogError("Error");

The method can be accessed through the interface reference.

When is it useful?

Default interface methods are particularly useful when evolving an existing interface without requiring every implementation to immediately add the new method.

Interview answer

Yes. Since C# 8.0, interfaces can contain default method implementations. This allows new functionality to be added to interfaces while reducing breaking changes for existing implementations. Implementing classes may use the default implementation or provide their own.

 

8. 🟡 Can an abstract class implement an interface without implementing all its members?

Yes. An abstract class can implement an interface without providing implementations for all interface members.

However, a concrete derived class must satisfy any remaining interface requirements.

C# example

public interface IEmployee
{
    void Work();
    void CalculateSalary();
}

public abstract class Employee : IEmployee
{
    public void Work()
    {
        Console.WriteLine("Employee working");
    }

    // Implementation deferred
    public abstract void CalculateSalary();
}

public class Developer : Employee
{
    public override void CalculateSalary()
    {
        Console.WriteLine("Salary calculated");
    }
}

Usage:

IEmployee emp = new Developer();

emp.Work();
emp.CalculateSalary();

Output:

Employee working
Salary calculated

Code explanation

  • IEmployee defines two methods.

  • The abstract Employee class implements Work().

  • CalculateSalary() remains abstract.

  • Developer implements the remaining method.

Real-time scenario

In an enterprise application, an abstract base service can implement common interface operations while leaving business-specific operations for derived services.

Interview answer

Yes, an abstract class can implement an interface without implementing all its members. The remaining members can be left for derived classes to implement. However, a concrete derived class must fulfill all required interface members before it can be instantiated.

 

9. 🟡 What are explicit and implicit interface implementations?

Implicit interface implementation

In implicit implementation, a class implements interface members using public methods or properties.

These members can be accessed through both the class and interface references.

C# example

public interface IPrinter
{
    void Print();
}

public class Printer : IPrinter
{
    public void Print()
    {
        Console.WriteLine("Printing document");
    }
}

Usage:

Printer printer = new Printer();

printer.Print(); // Allowed

IPrinter obj = printer;

obj.Print(); // Allowed

Explicit interface implementation

In explicit implementation, the interface name is included in the member declaration.

The implementation can only be accessed through an appropriate interface reference.

C# example

public interface IPrinter
{
    void Print();
}

public class Printer : IPrinter
{
    void IPrinter.Print()
    {
        Console.WriteLine("Printing document");
    }
}

Usage:

Printer printer = new Printer();

// printer.Print(); // Compilation error

IPrinter obj = printer;

obj.Print(); // Allowed

Real-time example: Two interfaces with the same method

public interface IEmail
{
    void Send();
}

public interface ISms
{
    void Send();
}

public class Notification : IEmail, ISms
{
    void IEmail.Send()
    {
        Console.WriteLine("Email sent");
    }

    void ISms.Send()
    {
        Console.WriteLine("SMS sent");
    }
}

Usage:

Notification notification = new Notification();

IEmail email = notification;
ISms sms = notification;

email.Send();
sms.Send();

Output:

Email sent
SMS sent

Comparison table

Feature

Implicit

Explicit

Method declaration

public void Print()

void IPrinter.Print()

Public class member

Yes

No

Accessible through class reference

Yes

No

Accessible through interface reference

Yes

Yes

Access modifier on implementation

Public

Cannot specify one

Best use

Normal interface implementation

Resolve name conflicts or hide interface-specific members

Interview answer

Implicit interface implementation uses public members that can be accessed through both class and interface references. Explicit interface implementation uses the interface name in the member declaration and can only be accessed through an interface reference. Explicit implementation is useful when multiple interfaces contain members with identical signatures that require different behavior.

 

10. 🟡 When would you choose an interface instead of an abstract class in a real project?

Explanation

Choose an interface when you need a contract that supports multiple implementations without forcing consumers to depend on a specific class hierarchy.

Choose an abstract class when related classes share common state or reusable implementation.

Real-time scenario: ASP.NET Core Web API

Suppose an application supports multiple notification providers:

  • Email

  • SMS

  • WhatsApp

Each provider performs the same logical operation but uses a different implementation.

Step 1: Define interface

public interface INotificationService
{
    Task SendAsync(string message);
}

Step 2: Implement services

public class EmailService : INotificationService
{
    public Task SendAsync(string message)
    {
        Console.WriteLine($"Email: {message}");
        return Task.CompletedTask;
    }
}

public class SmsService : INotificationService
{
    public Task SendAsync(string message)
    {
        Console.WriteLine($"SMS: {message}");
        return Task.CompletedTask;
    }
}

Step 3: Register service

builder.Services.AddScoped<
    INotificationService, EmailService>();

Step 4: Inject into controller

[ApiController]
[Route("api/notifications")]
public class NotificationController : ControllerBase
{
    private readonly INotificationService _service;

    public NotificationController(
        INotificationService service)
    {
        _service = service;
    }

    [HttpPost]
    public async Task<IActionResult> Send(
        [FromBody] string message)
    {
        await _service.SendAsync(message);

        return Ok("Notification sent");
    }
}

What happens when the implementation changes?

Suppose the application needs to switch from Email to SMS.

Only the dependency injection registration needs to change:

builder.Services.AddScoped<
    INotificationService, SmsService>();

The controller remains unchanged.

Application flow

Client
  |
  v
NotificationController
  |
  v
INotificationService
  |
  +-------------------+
  |                   |
  v                   v
EmailService       SmsService

The application selects the implementation through dependency injection configuration.

Interface vs Abstract class – Decision table

Scenario

Recommended

Dependency injection in ASP.NET Core

Interface

Multiple interchangeable implementations

Interface

Mocking or substituting dependencies in tests

Interface

Common contract across unrelated classes

Interface

Shared fields and constructors

Abstract class

Shared implemented methods

Abstract class

Strong base-class relationship

Abstract class

Common template with required override methods

Abstract class

Important design consideration

An interface is not mandatory for every class or service.

For example, if a simple internal class has only one implementation and no meaningful need for substitution, introducing an interface may add unnecessary complexity.

Also, interfaces and abstract classes can be used together when an application requires both a public contract and shared implementation.

Interview answer

I prefer interfaces when implementing dependency injection, loose coupling, multiple implementations, and testable services in ASP.NET Core. For example, controllers depend on IEmployeeService rather than EmployeeService. I choose abstract classes when related classes need shared fields, constructors, or common implemented methods.

 

Quick Interview Revision – All 10 Questions

Question

Key points to remember

1. Abstraction

Hide implementation, expose essential functionality

2. Abstract class

Common base, shared code, abstract methods

3. Interface

Contract, loose coupling, DI, testability

4. Abstract vs Interface

Shared implementation vs contract

5. Abstract class members

Constructors, fields, properties, methods

6. Multiple inheritance

One base class, multiple interfaces

7. Default interface methods

Supported since C# 8.0

8. Abstract class implementing interface

Can defer implementation to derived class

9. Explicit vs Implicit

Interface-only access vs public class access

10. Interface vs Abstract in projects

DI and interchangeable services vs shared base functionality

  1.  

Interview priority: Questions 1, 3, 4, 6, 9, and 10 are particularly valuable because interviewers frequently connect abstraction to real ASP.NET Core architecture, dependency injection, SOLID principles, and practical design decisions.

← Back to Articles