Monday, March 14, 2011

Interface or Abstract class

If you are one among who were searching for an answer to the question that what is difference between abstract class and interface then Abstract class Vs Interface provides you enough arsenal. However if you were looking for when to use which one, I will give you two SOLID reasons you should not use abstract classes and instead use interfaces.

SOLID principles are five majorly used guidelines that how should you design your classes. One such SOLID principle is Interface Segregation Principle (ISP). Another principle is The Liskov Substitution Principle (LSP). Interface segregation principle cannot be followed if you are leaning on abstract class. Substitution principle is itself a big problem and if try to work your way out of Substitution principle then you cannot rely on abstract classes. Let's see these two things in detail.

ISP – Many a times you will get into the argument that if an Abstract class is having all its methods as abstract then it is as good as an Interface. Technically yes, but there is more to it than just being technically correct. ISP tells me that make my interfaces as fine grained as I can make them. My interfaces should not be fat. This is so that my clients need not implement something that they were not interested in. Now take an example – Some behaviors of advance nature in Car object:

  1. Air Bag
  2. Alloy Wheels
  3. Power Steering
  4. ABS

Put these guys together in one interface and we have a fat interface, which not all client might be interested to implement. It will look something like this:

interface IAdvanceFeatures
{

AirBag();

AlloyWheel();

PowerSteering();

ABS();

}

Now if you need to apply ISP on it and implement it using abstract classes, then following would be the scenario:

abstract class AirBag
{
AirBag();
}

abstract class AlloyWheels
{

AlloyWheels();

}

I just separated only two features. But wait a minute. In my infinite wisdom I recalled that many modern programming languages stop you from multiple inheritance. Bingo… now you are in a soup where you want to use ISP but abstract classes are not letting you do it. This is one place where abstract class is bad guy.

LSP – Liskov Substitution Principle tells you that "Derived classes must be substitutable for their base classes". This means we should be able to use any of child class object in place of base class object. But in real time will you be able to create such inheritance hierarchy where child class can be substituted for base class. Not really because child class might have specialized something in such manner that it misbehaves when we put it in place of base class. I agree that such a behavior can be called a programming blunder but such is life. What are our alternatives? Our alternative is design by contract. Now contract can be in form of abstract class or interface. But as we established earlier there are limitations (having more than one abstract class) and you wouldn't want to have LSP on the cost of ISP. Would you? So option for abstract class is again stricken out. Sorry abstract class.

In a nutshell if you are trying to implement ISP and trying to stick to design by contract, abstract class is not a choice for you.

1 comment:

Nick said...

Thanks for this post Pradeep and your unique take on the question. I summarised the differences in a short article on my blog at http://kewney.com/posts/software-development/abstract-classes-vs-interfaces-in-c-sharp