Abstract Classes and Interfaces: Where Does Each Fit
A lot of times I find myself in certain programming forums, I come across this particular question: “what is the difference between an abstract class and an interface?” And it is usually asked by beginners to an object oriented programming language. In my case it is C#.
Even though (like I pointed out earlier) this question is common among beginners, you’ll also find out that certain programmers with quite some years of programming under their belts have the same issues some of it reflecting in the way they write their code.
So what are these two constructs? Are they the same or if not how do they differ? When can I use one above the other?
In the ensuing discussion, I will attempt to answer those questions starting from concept to code.
An abstract class is used to represent an abstract concept or entity that doesn’t map to any real object but is generic to a group of specific (real) objects it classifies. For example, when someone says something like, “Some wild animals don’t belong at home.” you are definitely prone to ask “what animal?” In this case you know what “class” of creatures (objects) the speaker is referring to but not the specific one hence the question that followed. “Animal”, is a generic term applicable to a class of living organisms that have certain similar characteristics. A dog (specific, real object) is an “animal” (generic, classifying term).
Another example can be if I ask you to draw a shape as against asking you to draw a rectangle. The first task cannot be undertaken as it is unclear what is requested. There really isn’t any physical representation for the former as compared to the latter. But the latter is a type of the former; rectangle is a shape.
Rectangle is a Shape Cat is a(n) Animal
Triangle is a Shape Monkey is a(n) Animal
As seen in the examples above, both “Shape” and “Animal” conceptually qualify to be represented as abstract classes.
Language Implementation (C#)
The normal flow in programming is from concept to code, hence having conceptually examined abstract classes, it is time to flesh them out in code. In C#, an abstract class is declared normally save with the preceding “abstract” keyword to qualify it as what it is.
public abstract class Shape
There are some things worth noting about abstract classes:
- They cannot be instantiated. True to the concept this class embodies, it doesn’t represent any real world object and thus cannot be instantiated.
- Contains a mixture of virtual and concrete methods. The virtual methods represent behaviours that vary from each deriving class and hence are declared with the “abstract” keyword and provide no implementation only method signature.
- All classes that inherit an abstract class must provide implementation for its abstract methods unless the class itself is an abstract class.
An interface represents a trait or behaviour any type can exhibit irrespective of hierarchy. Let’s say we have a Rectangle class that needs to print to screen and a Dog class that needs to be displayed on a screen as well.
Now we could easily implement a print or display method on each class and that would be perfectily fine. However, we could also define an IPrintable interface with a single method signature like so:
public interface IPrintable
The Rectangle and Dog classes can now implement this interface to provide the specific display form that suits each. Even though they don’t belong to the same hierarchy, they both exhibit the same behaviour: printing to display!
public Rectangle : Shape, IPrintable
public Dog : Animal, IPrintable
The interface just defines a universal behaviour or trait any type can implement or exhibit.
When then should I use each over the other:
- I want to define a class that represents something conceptual that serves as a base for other real representations of this concept — Abstract class.
- I want to define a universal behaviour or trait that can be manifested in ANY class — Interface
- I want to mix virtual and concrete members in a class — Abstract class
Understanding the concepts behind programming structures, constructs and technologies can aid the writing of easier to read and maintainable software over the long haul.