How should I have explained the difference between an Interface and an Abstract class?

Thinker picture Thinker · Sep 13, 2013 · Viewed 442.1k times · Source

In one of my interviews, I have been asked to explain the difference between an Interface and an Abstract class.

Here's my response:

Methods of a Java interface are implicitly abstract and cannot have implementations. A Java abstract class can have instance methods that implements a default behaviour.

Variables declared in a Java interface are by default final. An abstract class may contain non-final variables.

Members of a Java interface are public by default. A Java abstract class can have the usual flavours of class members like private, protected, etc.

A Java interface should be implemented using keyword “implements”; A Java abstract class should be extended using keyword “extends”.

An interface can extend another Java interface only, an abstract class can extend another Java class and implement multiple Java interfaces.

A Java class can implement multiple interfaces but it can extend only one abstract class.

However, the interviewer was not satisfied, and told me that this description represented "bookish knowledge".

He asked me for a more practical response, explaining when I would choose an abstract class over an interface, using practical examples.

Where did I go wrong?

Answer

Vimal Bera picture Vimal Bera · Sep 13, 2013

I will give you an example first:

public interface LoginAuth{
   public String encryptPassword(String pass);
   public void checkDBforUser();
}

Suppose you have 3 databases in your application. Then each and every implementation for that database needs to define the above 2 methods:

public class DBMySQL implements LoginAuth{
          // Needs to implement both methods
}
public class DBOracle implements LoginAuth{
          // Needs to implement both methods
}
public class DBAbc implements LoginAuth{
          // Needs to implement both methods
}

But what if encryptPassword() is not database dependent, and it's the same for each class? Then the above would not be a good approach.

Instead, consider this approach:

public abstract class LoginAuth{
   public String encryptPassword(String pass){
            // Implement the same default behavior here 
            // that is shared by all subclasses.
   }

   // Each subclass needs to provide their own implementation of this only:
   public abstract void checkDBforUser();
}

Now in each child class, we only need to implement one method - the method that is database dependent.