Abstract classes and interfaces can be used for similar purposes but it's important to understand the differences between the two.
An abstract class is a base class that has zero or more members that are abstract, meaning that they are declared but are not defined. Unlike regular classes, abstract classes cannot be instantiated and must be inherited.
You can make a class abstract by simply using the
abstract keyword before the
class keyword. Once you've done so, any of the class members (properties, fields, and methods) can also be declared abstract. An abstract member can't have an implementation. Note in the example below that the method has the
abstract keyword in its declaration and thus is not allowed to have a body (implementation).
One strength of abstract classes is that they allow you to have baseline functionality in your class but they can also require users of your class to implement their own aspects of the code. In the example below, there's an
EntityBase class that contains some default behavior like
IsValid because those methods have working implementations, but the
Validate method is abstract and requires the inheriting class to provide its own implementation. Notice how the
IsValid method even makes use of the
Validate method, even though it's not defined.
Another strength of abstract classes is that you can make non-public members abstract. In other words, you can force the user of your class to implement protected and internal members, in addition to public ones.
A weakness of abstract classes is that you cannot inherit from more than one of them.
An interface is a contract that has zero or more members that must be implemented by any class that implements the interface. As of C# 8.0, interfaces may contain default implementations, in which case, the implementing class will not be required to implement members for which there are default implementations. Like an abstract class, interfaces cannot be instantiated.
To implement an interface, you simply specify the interface after the class name as shown below. In the example below, there's a
Person class that implements an
IEntity interface. The interface defines some members that the class must implement to be a valid
One strength of interfaces is that you can implement as many of them as you'd like. So you could have a
FordFusion class that implements both
IGasPoweredVehicle. This would allow you to pass an instance of your
FordFusion class into any methods that accept
Members of interfaces are always public. This could be considered a weakness, but it's also kind of the defining characteristic of interfaces, so it's hard to call it such. Either way, it's definitely something to be aware of.
A weakness of interfaces is that, before C# 8.0, they couldn't have default implementations. As of C# 8.0, you can have default implementations in interfaces, but said behavior can only interact with members that the interface has declared. And because interface members can only be public, this means that your default implementations can only deal with members that are also public.
Here's the same interface example as above, but this time, we're taking advantage of C# 8.0's default implementations support. Notice how we don't have to declare the
IsValid methods on the
Person class because
IEntity contains default implementations of those members. We could still declare those methods if we wanted to supply our own implementations, but we're no longer required to.
The following table is an at-a-glance comparison between the two code constructs.
|Default Implementations||Yes.||Yes (in C# 8.0).|
|Access Modifiers||Yes.||No, everything is public.|
When to Use
Use an abstract class if:
- You have a base class that needs to utilize private, protected, or internal members.
Use an interface if:
- You want to support multiple inheritance.
- You want default implementations that may or may not make use of other interface members. (Only applies to C# 8.0 or greater)
- You want to apply to a