Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between abstract class with all method abstract and interface?

I had an interview where interviewer asked me first what is the difference between abstract class with all the methods abstract and an interface.

I replied that if it is required to inherit something in the future you will not be able to do it if you have already extended a class.

Then, he stated that it was a situation where one would never have to extend any other class and you have to implement a contract. In this circumstance, which would be better, an abstract class or an interface?

I told him you can use either of them but he was not satisfied. I could not understand why - I believe that is a developer/design choice.

like image 762
Dangling Piyush Avatar asked Apr 25 '14 20:04

Dangling Piyush


1 Answers

The answer stating that an interface represents a contract is not acceptable. That's the answer we give to Junior since it may be too complex to clearly figure out the difference between the essence of an abstract class and the essence of an interface without much architecture experience and without reading a lot of classic books about. Any abstract class with public methods acts as a contract, as well as an interface.

An abstract class that doesn't provide any implementation is in 99% of cases a representation of an object's Role.
An interface represents a Role.
Each object might have several different roles that shouldn't be tied together but composed by the concerned object.

I'm explaining this with this example:

Your interviewer could say:
I have a Robot that can walk and a Human that can walk too.

So based on this case, he asks you: should I extract the walking feature in an abstract base class or in an interface, knowing that the implementations have nothing in common?

You think..."oh I know so: in this case, having one abstract class with an abstract method walk(), then is clearly the same than declaring an interface with the walk() method."
So your answer would surely be: "it's the choice of the developer !".
And it's really not an always valid answer.

Why? Let's see the next expectation:
A Human can eat, but obviously the Robot cannot and even doesn't need.

What if you implemented the walking feature with an abstract class? You would end up with:

public abstract class Biped {  
  public void abstract walk();
} 

public Robot extends Biped {
   public void walk() {
     //walk at 10km/h speed
   }
}

public Human extends Biped {
   public void walk() {
     //walk at 5km/h speed
   }
}

How could you plug the eating feature? You're stuck because you can't implement it in the Biped base class since it would break Liskov Substitution Principle, since a Robot doesn't eat! And you can't expect Human extending another base class due to the known Java rule.

Of course, you could add a specific Feedable interface only dedicated to Human:

public interface Feedable {
  void eat();
} 

Signature becomes: public Human extends Biped implements Feedable { Clearly, it makes no sense and confusing to have one role implemented through a class and the other through an interface.

That's why starting with interface is really preferred whenever we have the choice.

With an interface, we can model Roles easily by composing.

So the final solution would then be:

public interface Walkable {
   void abstract walk();
} 

public interface Feedable {
   void eat();
} 

public Robot implements Walkable {
   public void walk() {
     //walk at 10km/h speed
   }
}

public Human implements Walkable, Feedable {
   public void walk() {
     //walk at 5km/h speed
   }

   public void eat(){
     //...
   }    
}

Doesn't it remind you the Interface Segregation Principle? ;)

To sum up, if you specify an IS-A relationship, uses an abstract class. If you realize that you are about to model a Role (let's say a IS-CAPABLE-OF relationship), go with interface.

like image 134
Mik378 Avatar answered Oct 12 '22 23:10

Mik378