Technical Articles

Interview Series: Abstract Class vs Interface in C#

0 0

Interview Series: Abstract Class vs Interface in C#

Interviewer Question 1: What is the basic difference between an abstract class and an interface in C#?

Answer: The main difference is that an abstract class can have both abstract methods (without implementation) and concrete methods (with implementation), while an interface only defines abstract methods (until C# 8.0, where default implementations were introduced).

  • Abstract Class: Can have both method definitions and implementations.
  • Interface: Defines only method signatures, and any class implementing the interface must provide implementations for all its members.

Interviewer Question 2: Can you explain the usage scenarios for abstract class vs interface?

Answer: An abstract class is used when you want to provide some common functionality along with abstract methods that subclasses must implement. It’s ideal when you have a common base class for related objects.

An interface is used when you want to enforce a contract for multiple unrelated classes. It’s ideal for scenarios where multiple implementations are expected but they do not need to share common behavior.

Example:

  • Use an abstract class for vehicles (e.g., Car, Bike) to provide a method like DisplayInfo(), but leave CalculateFuelEfficiency() to be implemented by each vehicle.
  • Use an interface when you want all payment methods (CreditCardPayment, PayPalPayment) to implement the ProcessPayment() method without shared behavior.

Interviewer Question 3: Can an abstract class have a constructor?

Answer: Yes, an abstract class can have a constructor. Although you cannot instantiate an abstract class directly, the constructor is called when a subclass is instantiated. It is used to initialize common properties for all subclasses.

Example:


public abstract class Vehicle
{
    public string Name { get; set; }
    public Vehicle(string name)
    {
        Name = name;
    }
}

public class Car : Vehicle
{
    public Car(string name) : base(name) {}
}

    

When you instantiate Car, the constructor of Vehicle will be invoked to initialize the Name property.

Interviewer Question 4: Can a class implement multiple interfaces? What about inheriting multiple abstract classes?

Answer: Yes, a class can implement multiple interfaces. This is one of the key benefits of using interfaces as it allows for multiple inheritance of behavior.

However, a class cannot inherit from multiple abstract classes, as C# does not support multiple inheritance for classes. A class can inherit from only one abstract class but can implement multiple interfaces.

Example:


public class Car : Vehicle, IPaymentProcessor, IComparable
{
    // Implement abstract methods from Vehicle and interface methods
}

    

Interviewer Question 5: How would you decide when to use an abstract class over an interface?

Answer:

  • Use an abstract class when:
    • You need to share common behavior or logic between subclasses.
    • You expect some methods to be the same across all subclasses (i.e., shared logic).
    • The classes share an “is-a” relationship (e.g., a Car is a Vehicle).
  • Use an interface when:
    • You want to enforce a contract for unrelated classes that don’t need common behavior.
    • You need multiple inheritance (since a class can implement multiple interfaces).
    • The classes share a “can-do” relationship (e.g., a class that can-do IDisposable, IPaymentProcessor).

Interviewer Question 6: Can you give a real-time example for when you’d use an interface in C#?

Answer: Consider a payment processing system. You may have different types of payments like CreditCardPayment, PayPalPayment, or BankTransferPayment, and they all need to implement a method ProcessPayment().


public interface IPaymentProcessor
{
    void ProcessPayment(double amount);
}

public class CreditCardPayment : IPaymentProcessor
{
    public void ProcessPayment(double amount)
    {
        Console.WriteLine($"Processing Credit Card Payment of ${amount}");
    }
}

public class PayPalPayment : IPaymentProcessor
{
    public void ProcessPayment(double amount)
    {
        Console.WriteLine($"Processing PayPal Payment of ${amount}");
    }
}

    

This ensures that all payment methods implement the ProcessPayment() method, making it easier to extend the system when a new method, like BitcoinPayment, is added.

Interviewer Question 7: What are some best practices when using abstract classes and interfaces?

Answer:

  • Use abstract classes if you need to provide a common base and shared functionality for derived classes.
  • Use interfaces for loose coupling and flexibility, especially in scenarios where you expect many implementations of the same functionality.
  • Favor interfaces over abstract classes if you foresee the need for multiple inheritance.
  • Keep your interfaces small and focused on one responsibility. Avoid creating “fat” interfaces that require too many methods to be implemented by classes.

Interviewer Question 8: What are the limitations of abstract classes and interfaces? When should you NOT use each?

Limitations of Abstract Classes

  • No multiple inheritance: A class can only inherit one abstract class, limiting flexibility.
  • Tighter coupling: Abstract classes can tightly couple base and derived classes, making it harder to introduce changes.

When NOT to use Abstract Classes

  • If you need multiple inheritance.
  • If the classes are unrelated.

Limitations of Interfaces

  • Cannot share common code: Interfaces only define signatures, not implementations.
  • Versioning issues: Adding methods to an interface requires all implementing classes to update their code.

When NOT to use Interfaces

  • If you want to provide shared behavior.
  • If maintaining backward compatibility is crucial.

Real-World Example of Using Abstract Classes and Interfaces

Scenario: Payment Processing System

Using abstract classes and interfaces, you can create a flexible and scalable payment system.

Abstract Class Example:


public abstract class PaymentProcessor
{
    public void LogTransaction(double amount)
    {
        Console.WriteLine($"Logging transaction of ${amount}");
    }

    public abstract void ProcessPayment(double amount);
}

public class CreditCardPayment : PaymentProcessor
{
    public override void ProcessPayment(double amount)
    {
        LogTransaction(amount);
        Console.WriteLine($"Processing Credit Card Payment of ${amount}");
    }
}

    

Interface Example:


public interface IPaymentProcessor
{
    void ProcessPayment(double amount);
}

public class PayPalPayment : IPaymentProcessor
{
    public void ProcessPayment(double amount)
    {
        Console.WriteLine($"Processing PayPal Payment of ${amount}");
    }
}

    
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x
× How can I help you?