When to use an abstract class vs. interface in C#

By Joydip Kanjilal

When designing applications, it is important to know when to use an abstract class and when to use an interface. Although abstract classes and interfaces seem similar in some ways, there are key differences that will determine which is the best choice for what you’re trying to accomplish. In this blog post I’ll discuss those differences and how to decide when to use which.

The short answer: An abstract class allows you to create functionality that subclasses can implement or override. An interface only allows you to define functionality, not implement it. And whereas a class can extend only one abstract class, it can take advantage of multiple interfaces.

C# abstract class explained

An abstract class is a special type of class that cannot be instantiated. An abstract class is designed to be inherited by subclasses that either implement or override its methods. In other words, abstract classes are either partially implemented or not implemented at all. You can have functionality in your abstract class—the methods in an abstract class can be both abstract and concrete. An abstract class can have constructors—this is one major difference between an abstract class and an interface. You can take advantage of abstract classes to design components and specify some level of common functionality that must be implemented by derived classes.

C# interface explained

An interface is basically a contract—it doesn’t have any implementation. An interface can contain only method declarations; it cannot contain method definitions. Nor can you have any member data in an interface. Whereas an abstract class may contain method definitions, fields, and constructors, an interface may only have declarations of events, methods, and properties. Methods declared in an interface must be implemented by the classes that implement the interface. Note that a class can implement more than one interface but extend only one class. The class that implements the interface should implement all its members. Like an abstract class, an interface cannot be instantiated.

Key similarities between abstract classes and interfaces in C#

There are four key similarities between interfaces and abstract classes.

Behavior without implementation: The C# programming language provides both interfaces and abstract classes to define behavior without implementation. You can take advantage of an interface or an abstract class to define a contract that must be followed by types that extend or implement that interface or abstract class. For example, you can define methods, properties, and events in an interface or an abstract class that must be implemented by types that extend it. However, from C# 8.0 onward, an interface can contain default implementations for its members, i.e. methods and properties.

No instantiation: You can use both abstract classes and interfaces to define types that cannot be instantiated. Instead, you must implement an interface or extend an abstract class by other types.

Support for polymorphism: You can achieve polymorphism using both interface and abstract classes. Most importantly, you can have a derived class extend an abstract base class and implement multiple interfaces.

Access modifiers: Methods in both interfaces and abstract classes can include access modifiers. However, it should be noted that from C# 7.2, all members in an interface are public by default.

Key differences between abstract classes and interfaces in C#

While there are certain similarities between interfaces and abstract classes, there are also subtle differences.

Default implementations: You can have methods in an abstract class that have default implementations. However, interfaces did not support default implementations for its members until recently. With C# 8.0, you can have default implementations for the members of an interface, similar to abstract classes.

Member types: In an abstract class, you can have several member types such as fields, constructors, destructors, and static members. You also can have constructors in an abstract class, but you cannot have constructors in an interface. To define a destructor in any class in C#, you prefix the name of the destructor with a tilde (~\) sign.

State: Moreover, abstract classes can have state information, i.e., they can have fields. However, you cannot have instance fields in interfaces. This is why you can serialize an abstract class but you can never serialize an interface. Because you can serialize only a class, a struct, an enum, or a delegate. When you serialize an abstract class, it is the instance of the derived class that extends the abstract class that is actually serialized.

Inheritance: Although a class can extend only a single abstract class, it can implement several interfaces. By implementing multiple interfaces, you can simulate multiple inheritance by leveraging interfaces in C#.

Advantages of using abstract classes instead of interfaces in certain scenarios

Abstract classes provide structural, behavioral, and design capabilities that make them a good choice in certain scenarios.

State management: You can use abstract classes to maintain state information that the derived classes can access.

Access modifiers: You can use abstract classes with access modifiers that provide fine-grained control over its members.

Constructors and destructors: You can have constructors and destructors in an abstract class, allowing you to initialize its members and write code for cleanup logic. Thus you can initialize the members of the abstract class when an instance of any of its derived classes is created and retrieve memory resources when these instances are destroyed.

Advantages of using interfaces instead of abstract classes in certain scenarios

There are also certain advantages of using interfaces instead of abstract classes.

Multiple implementations: Interfaces are preferred over abstract classes when you would like to establish contracts in your application without enforcing a direct lineage. A class can implement several interfaces, allowing it to conform to numerous contracts simultaneously. This can help you create components that take advantage of cross-cutting concerns in an application.

Modularity: Interfaces foster a design in which you define a contract that any implementing class must adhere to, thereby promoting a modular, extensible, and flexible architecture that makes your code easier to test, extend, and maintain.

Mocking: You can use interfaces to create mock objects when writing your unit tests. Because you can define behavior without implementation in an interface, you can use interfaces to create unit tests that do not depend on implementations defined in concrete classes.

Design flexibility: You can take advantage of interfaces to create applications with evolving designs by leveraging the default implementation feature introduced in C# 8.0. Hence, you can use interfaces to create applications that are flexible and evolving without breaking existing implementations. By programming to an interface instead of its implementations, you can work with abstractions in lieu of concrete classes. This fosters a design in which components are interchangeable as long as they adhere to the same contract defined by the interface that they implement.

Should I use an abstract class or an interface?

Abstract classes provide you the flexibility to have certain concrete methods and some other methods that the derived classes should implement. By contrast, if you use interfaces, you would need to implement all the methods in the class that extends the interface. An abstract class is a good choice if you have plans for future expansion – i.e. if a future expansion is likely in the class hierarchy. If you would like to provide support for future expansion when using interfaces, you’ll need to extend the interface and create a new one.

On a different note, it is easy to add a new interface to the hierarchy if need be. However, if you already have an abstract class in your hierarchy, you can’t add another—i.e., you can add an abstract class only if none are available. You should use an interface if you want a contract on some behavior or functionality. You should not use an interface if you need to write the same code for the interface methods. In this case, you should use an abstract class, define the method once, and reuse it as needed. Do use interfaces to decouple your application’s code from specific implementations of it, or to restrict access to members of a certain type.

As Microsoft’s documentation of interfaces states:

By using interfaces, you can, for example, include behavior from multiple sources in a class. That capability is important in C# because the language doesn’t support multiple inheritance of classes. In addition, you must use an interface if you want to simulate inheritance for structs, because they can’t actually inherit from another struct or class.

Implicit and explicit interface implementations

Interfaces can be implemented implicitly or explicitly. Let me explain how these two implementations differ. Consider an interface called IBusinessLogic.

public interface IBusinessLogic{ void Initialize();}

The following class named BusinessLogic implements the IBusinessLogic interface.

public class BusinessLogic : IBusinessLogic{ public void Initialize() { //Some code }}

You can create an instance of the BusinessLogic class explicitly and then call the Initialize() method as shown below.

IBusinessLogic businessLogic = new BusinessLogic();businessLogic.Initialize();

The following code snippet illustrates how you can implement the IBusinessLogic interface implicitly.

public class BusinessLogic : IBusinessLogic{ void IBusinessLogic.Initialize() { }}

You can now invoke the Initialize() method the same way using a reference to the IBusinessLogic interface. The difference in the two approaches is that when you implement the interface explicitly in your class, you are constrained to invoking a method of your interface using a reference to the interface only. Therefore the following code snippet would not work, i.e. would not compile.

BusinessLogic businessLogic = new BusinessLogic();businessLogic.Initialize();

Abstract classes vs. interfaces in C# FAQs

What is the fundamental difference between an abstract class and an interface?

Although interfaces in C# can have only properties, abstract classes in C# may have properties and fields. Typically, we use abstract classes to create an abstract base class that other classes can extend. On the other hand, interfaces are implemented by classes to conform to a contract.

With C# 8.0, an interface can have static, virtual, abstract, sealed, private, and extern members. However, an interface cannot have constructors or destructors in any versions of the C# programming language.

Can a class inherit from multiple interfaces or abstract classes?

A class in C# can implement multiple interfaces, but it can inherit from one and only one abstract class.

When should I use an abstract class over an interface?

We should use an abstract class when we need to define state information and specify how the fields should be initialized.

Can an abstract class or an interface contain fields?

An abstract class can contain fields but you cannot have fields in an interface. This explains why you cannot serialize an interface in C#.

How do default implementations in C# 8.0 affect the difference between abstract classes and interfaces?

With the introduction of C# 8.0, interfaces can have default implementations for their members. However, they still cannot have constructors or fields. And unlike the methods of an abstract class, the default implementations of interfaces cannot access private fields.

How do abstract classes and interfaces in C# differ in performance?

The performance difference between interfaces and abstract classes depends on the implementation. You can have several member definitions in an abstract class or an interface. You can also make your interface or abstract class lightweight by having only member declarations. However, because abstract classes can have constructors and virtual methods, they tend to require more memory and CPU resources than interfaces.

In other words, you incur a slight performance penalty when using abstract classes. Microsoft recommends using concrete types whenever possible for better performance.

© Info World