Classes and Interfaces

Posted on January 27th, 2007 in OO Concepts by Puneet Sarda

When coming up with application architecture, it’s common to run into situations where you have to decide if to use a class or create an interface. Abstract classes with all virtual methods appear to look just like an interface with a bunch of methods in it. However when designing classes and hierarchies of classes we also need to make sure that types of a particular kind are implemented such that the relation between them is evident.

Abstract classes and derived classes indicate the IS-A relationship. Any of the objects of the derived classes have come common characteristics which make them similar to each other. A honda civic and a toyota camry “is a” kind of car. I could make an abstract car class and derive the civic and camry class from it hence making them cars inherently. Or I could create an interface which would have methods and properties defining the characteristics of a car and then have civic and camry implement that interface. From a functionality perspective, either way, the civic and camry classes do the same functions. But if you look at the design of classes, it is counterintuitive when you use interface in this scenario. And that is the most important part of designing class hierarchies or for that matter type hierarchies. The design has to be intuitive to another developer who reads your code. Interfaces indicate a “CAN-DO” relationship indicating that any calss who implements it, in addition to its inherent functions and logic, can also do this particular action.

When  building an application, being concerned about such design issues helps you in maintaining the application as years go by and new modules get added. However the scenario is very different if you design an applicaiton framework to be used by other developers for making their programs. Then decisions about whether something should be an abstract class or an interface can have a huge impact.

As Brad Abrams points out in Framework Design Guidelines “The main drawback of interfaces is that they are much less flexible than classes when it comes to allowing for evolution of APIs”. The idea being if you ship an interface and later want to add other methods/properties to it, you can’t as that is a breaking change. Everyonre who is using your interface in its v1 when they get the v2, the compiler will complain that the interface is not implemented completely. There might be a few ways to get around the issue but none of them are elegant or intuitive.

I will close with the recommendation from Jeffrey Richter in the same book

“Define an interface first and then define an abstract base class that implements the interface. Use the interface to communicate to the object and let end-user developers decide for themselves whether they can just define their own type based on your abstract base class(for convenience) or define their own type based on whatever base class they desire and implement the interface(for flexibility). A good example of this is the IComponent interface and the Component base class that implements IComponent.”

Again…most importantly use your judgement as these and many other rules are just rules of thumb. For your application or framework decide whats the most appropriate option. For reference Section 4.3 in Framework Design Guidelines explores the interface/class issue in good detail.