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



14 Answers

Nothing is perfect in this world. They may have been expecting more of a practical approach.

But after your explanation you could add these lines with a slightly different approach.

  1. Interfaces are rules (rules because you must give an implementation to them that you can't ignore or avoid, so that they are imposed like rules) which works as a common understanding document among various teams in software development.

  2. Interfaces give the idea what is to be done but not how it will be done. So implementation completely depends on developer by following the given rules (means given signature of methods).

  3. Abstract classes may contain abstract declarations, concrete implementations, or both.

  4. Abstract declarations are like rules to be followed and concrete implementations are like guidelines (you can use it as it is or you can ignore it by overriding and giving your own implementation to it).

  5. Moreover which methods with same signature may change the behaviour in different context are provided as interface declarations as rules to implement accordingly in different contexts.

Edit: Java 8 facilitates to define default and static methods in interface.

public interface SomeInterfaceOne {

    void usualAbstractMethod(String inputString);

    default void defaultMethod(String inputString){
        System.out.println("Inside SomeInterfaceOne defaultMethod::"+inputString);
    }
}

Now when a class will implement SomeInterface, it is not mandatory to provide implementation for default methods of interface.

If we have another interface with following methods:

public interface SomeInterfaceTwo {

    void usualAbstractMethod(String inputString);

    default void defaultMethod(String inputString){
        System.out.println("Inside SomeInterfaceTwo defaultMethod::"+inputString);
    }

}

Java doesn’t allow extending multiple classes because it results in the “Diamond Problem” where compiler is not able to decide which superclass method to use. With the default methods, the diamond problem will arise for interfaces too. Because if a class is implementing both

SomeInterfaceOne and SomeInterfaceTwo

and doesn’t implement the common default method, compiler can’t decide which one to chose. To avoid this problem, in java 8 it is mandatory to implement common default methods of different interfaces. If any class is implementing both the above interfaces, it has to provide implementation for defaultMethod() method otherwise compiler will throw compile time error.

Question

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?




I will try to answer using practical scenario to show the distinction between the two.

Interfaces come with zero payload i.e. no state has to be maintained and thus are better choice to just associate a contract (capability) with a class.

For example, say I have a Task class that performs some action, now to execute a task in separate thread I don't really need to extend Thread class rather better choice is to make Task implement Runnable interface (i.e. implement its run() method) and then pass object of this Task class to a Thread instance and call its start() method.

Now you can ask what if Runnable was a abstract class?

Well technically that was possible but design wise that would have been a poor choice reason being:

  • Runnable has no state associated with it and neither it 'offers' any default implementation for the run() method
  • Task would have to extend it thus it couldn't extend any other class
  • Task has nothing to offer as specialization to Runnable class, all it needs is to override run() method

In other words, Task class needed a capability to be run in a thread which it achieved by implementing Runnable interface verses extending the Thread class that would make it a thread.

Simply put us interface to define a capability (contract), while use a abstract class to define skeleton (common/partial) implementation of it.

Disclaimer: silly example follows, try not to judge :-P

interface Forgiver {
    void forgive();
}

abstract class GodLike implements Forgiver {
    abstract void forget();
    final void forgive() {
        forget();
    }
}

Now you have been given a choice to be GodLike but you may choose to be Forgiver only (i.e. not GodLike) and do:

class HumanLike implements Forgiver {
    void forgive() {
       // forgive but remember    
    }
}

Or you may may choose to be GodLike and do:

class AngelLike extends GodLike {
    void forget() {
       // forget to forgive     
    }
}

P.S. with java 8 interface can also have static as well default (overridable implementation) methods and thus difference b/w interface and abstract class is even more narrowed down.




From what I understand and how I approach,

Interface is like a specification/contract, any class that implements a interface class have to implement all the methods defined in the abstract class (except default methods (introduced in java 8))

Whereas I define a class abstract when I know the implementation required for some methods of the class and some methods I still do not know what will be the implementation(we might know the function signature but not the implementation). I do this so that later in the part of development when i know how these methods are to be implemented, i can just extend this abstract class and implement these methods.

Note: You cannot have function body in interface methods unless the method is static or default.




Your answer is ok, but I think he was looking for this kind of answer:

Abstract class

  • Abstract class can have abstract and non-abstract methods.
  • Abstract class doesn't support multiple inheritance.
  • Abstract class can have final, non-final, static and non-static variables.
  • Abstract class can provide the implementation of interface.

Interface

  • Interface can have default, static and abstract methods.
  • Interface supports multiple inheritance.
  • Interface has only static and final variables.
  • Interface can't provide the implementation of abstract class.



hmm now the people are hungery practical approach, you are quite right but most of interviewer looks as per their current requirment and want a practical approach.

after finishing your answer you should jump on the example:

Abstract:

for example we have salary function which have some parametar common to all employee. then we can have a abstract class called CTC with partialy defined method body and it will got extends by all type of employee and get redeined as per their extra beefits. For common functonality.

public abstract class CTC {

    public int salary(int hra, int da, int extra)
    {
        int total;
        total = hra+da+extra;
        //incentive for specific performing employee
        //total = hra+da+extra+incentive;
        return total;
    }
}

class Manger extends CTC
{
}


class CEO extends CTC
{
}

class Developer extends CTC
{   
}

Interface

interface in java allow to have interfcae functionality without extending that one and you have to be clear with the implementation of signature of functionality that you want to introduce in your application. it will force you to have definiton. For different functionality. public interface EmployeType {

    public String typeOfEmployee();
}

class ContarctOne implements EmployeType
{

    @Override
    public String typeOfEmployee() {
        return "contract";
    }

}

class PermanentOne implements EmployeType
{

    @Override
    public String typeOfEmployee() {
        return "permanent";
    }

}

you can have such forced activity with abstract class too by defined methgos as a abstract one, now a class tha extends abstract class remin abstract one untill it override that abstract function.




From what I understand, an Interface, which is comprised of final variables and methods with no implementations, is implemented by a class to obtain a group of methods or methods that are related to each other. On the other hand, an abstract class, which can contain non-final variables and methods with implementations, is usually used as a guide or as a superclass from which all related or similar classes inherits from. In other words, an abstract class contains all the methods/variables that are shared by all its subclasses.







An interface is like a set of genes that are publicly documented to have some kind of effect: A DNA test will tell me whether I've got them - and if I do, I can publicly make it known that I'm a "carrier" and part of my behavior or state will conform to them. (But of course, I may have many other genes that provide traits outside this scope.)

An abstract class is like the dead ancestor of a single-sex species(*): She can't be brought to life but a living (i.e. non-abstract) descendant inherits all her genes.

(*) To stretch this metaphor, let's say all members of the species live to the same age. This means all ancestors of a dead ancestor must also be dead - and likewise, all descendants of a living ancestor must be alive.




Difference between Abstact class and interface

  1. Abstract classes versus interfaces in Java 8
  2. Conceptual Difference:

Interface Default Methods in Java 8

  1. What is Default Method?
  2. ForEach method compilation error solved using Default Method
  3. Default Method and Multiple Inheritance Ambiguity Problems
  4. Important points about java interface default methods:

Java Interface Static Method

  1. Java Interface Static Method, code example, static method vs default method
  2. Important points about java interface static method:

Java Functional Interfaces



Abstract classes versus interfaces in Java 8

Java 8 interface changes include static methods and default methods in interfaces. Prior to Java 8, we could have only method declarations in the interfaces. But from Java 8, we can have default methods and static methods in the interfaces.

After introducing Default Method, it seems that interfaces and abstract classes are same. However, they are still different concept in Java 8.

Abstract class can define constructor. They are more structured and can have a state associated with them. While in contrast, default method can be implemented only in the terms of invoking other interface methods, with no reference to a particular implementation's state. Hence, both use for different purposes and choosing between two really depends on the scenario context.

Conceptual Difference:

Abstract classes are valid for skeletal (i.e. partial) implementations of interfaces but should not exist without a matching interface.

So when abstract classes are effectively reduced to be low-visibility, skeletal implementations of interfaces, can default methods take this away as well? Decidedly: No! Implementing interfaces almost always requires some or all of those class-building tools which default methods lack. And if some interface doesn’t, it is clearly a special case, which should not lead you astray.

Interface Default Methods in Java 8

Java 8 introduces “Default Method” or (Defender methods) new feature, which allows developer to add new methods to the Interfaces without breaking the existing implementation of these Interface. It provides flexibility to allow Interface define implementation which will use as default in the situation where a concrete Class fails to provide an implementation for that method.

Let consider small example to understand how it works:

public interface OldInterface {
    public void existingMethod();
 
    default public void newDefaultMethod() {
        System.out.println("New default method"
               + " is added in interface");
    }
}

The following Class will compile successfully in Java JDK 8,

public class OldInterfaceImpl implements OldInterface {
    public void existingMethod() {
     // existing implementation is here…
    }
}

If you create an instance of OldInterfaceImpl:

OldInterfaceImpl obj = new OldInterfaceImpl ();
// print “New default method add in interface”
obj.newDefaultMethod(); 

Default Method:

Default methods are never final, can not be synchronized and can not override Object’s methods. They are always public, which severely limits the ability to write short and reusable methods.

Default methods can be provided to an Interface without affecting implementing Classes as it includes an implementation. If each added method in an Interface defined with implementation then no implementing Class is affected. An implementing Class can override the default implementation provided by the Interface.

Default methods enable to add new functionality to existing Interfaces without breaking older implementation of these Interfaces.

When we extend an interface that contains a default method, we can perform following,

  1. Not override the default method and will inherit the default method.
  2. Override the default method similar to other methods we override in subclass.
  3. Redeclare default method as abstract, which force subclass to override it.

ForEach method compilation error solved using Default Method

For Java 8, the JDK collections have been extended and forEach method is added to the entire collection (which work in conjunction with lambdas). With conventional way, the code looks like below,

public interface Iterable<T> {
    public void forEach(Consumer<? super T> consumer);
}

Since this result each implementing Class with compile errors therefore, a default method added with a required implementation in order that the existing implementation should not be changed.

The Iterable Interface with the Default method is below,

public interface Iterable<T> {
    public default void forEach(Consumer
                   <? super T> consumer) {
        for (T t : this) {
            consumer.accept(t);
        }
    }
}

The same mechanism has been used to add Stream in JDK Interface without breaking the implementing Classes.


Default Method and Multiple Inheritance Ambiguity Problems

Since java Class can implement multiple Interfaces and each Interface can define default method with same method signature, therefore, the inherited methods can conflict with each other.

Consider below example,

public interface InterfaceA {  
       default void defaultMethod(){  
           System.out.println("Interface A default method");  
    }  
}
 
public interface InterfaceB {
   default void defaultMethod(){
       System.out.println("Interface B default method");
   }
}
 
public class Impl implements InterfaceA, InterfaceB  {
}

The above code will fail to compile with the following error,

java: class Impl inherits unrelated defaults for defaultMethod() from types InterfaceA and InterfaceB

In order to fix this class, we need to provide default method implementation:

public class Impl implements InterfaceA, InterfaceB {
    public void defaultMethod(){
    }
}

Further, if we want to invoke default implementation provided by any of super Interface rather than our own implementation, we can do so as follows,

public class Impl implements InterfaceA, InterfaceB {
    public void defaultMethod(){
        // existing code here..
        InterfaceA.super.defaultMethod();
    }
}

We can choose any default implementation or both as part of our new method.

Important points about java interface default methods:

  1. Java interface default methods will help us in extending interfaces without having the fear of breaking implementation classes.
  2. Java interface default methods has bridge down the differences between interfaces and abstract classes.
  3. Java 8 interface default methods will help us in avoiding utility classes, such as all the Collections class method can be provided in the interfaces itself.
  4. Java interface default methods will help us in removing base implementation classes, we can provide default implementation and the implementation classes can chose which one to override.
  5. One of the major reason for introducing default methods in interfaces is to enhance the Collections API in Java 8 to support lambda expressions.
  6. If any class in the hierarchy has a method with same signature, then default methods become irrelevant. A default method cannot override a method from java.lang.Object. The reasoning is very simple, it’s because Object is the base class for all the java classes. So even if we have Object class methods defined as default methods in interfaces, it will be useless because Object class method will always be used. That’s why to avoid confusion, we can’t have default methods that are overriding Object class methods.
  7. Java interface default methods are also referred to as Defender Methods or Virtual extension methods.

Resource Link:

  1. Interface with default methods vs Abstract class in Java 8
  2. Abstract class versus interface in the JDK 8 era
  3. Interface evolution via virtual extension methods

Java Interface Static Method

Java Interface Static Method, code example, static method vs default method

Java interface static method is similar to default method except that we can’t override them in the implementation classes. This feature helps us in avoiding undesired results incase of poor implementation in implementation classes. Let’s look into this with a simple example.

public interface MyData {

    default void print(String str) {
        if (!isNull(str))
            System.out.println("MyData Print::" + str);
    }

    static boolean isNull(String str) {
        System.out.println("Interface Null Check");

        return str == null ? true : "".equals(str) ? true : false;
    }
}

Now let’s see an implementation class that is having isNull() method with poor implementation.

public class MyDataImpl implements MyData {

    public boolean isNull(String str) {
        System.out.println("Impl Null Check");

        return str == null ? true : false;
    }

    public static void main(String args[]){
        MyDataImpl obj = new MyDataImpl();
        obj.print("");
        obj.isNull("abc");
    }
}

Note that isNull(String str) is a simple class method, it’s not overriding the interface method. For example, if we will add @Override annotation to the isNull() method, it will result in compiler error.

Now when we will run the application, we get following output.

Interface Null Check

Impl Null Check

If we make the interface method from static to default, we will get following output.

Impl Null Check

MyData Print::

Impl Null Check

Java interface static method is visible to interface methods only, if we remove the isNull() method from the MyDataImpl class, we won’t be able to use it for the MyDataImpl object. However like other static methods, we can use interface static methods using class name. For example, a valid statement will be:

boolean result = MyData.isNull("abc");

Important points about java interface static method:

  1. Java interface static method is part of interface, we can’t use it for implementation class objects.
  2. Java interface static methods are good for providing utility methods, for example null check, collection sorting etc.
  3. Java interface static method helps us in providing security by not allowing implementation classes to override them.
  4. We can’t define interface static method for Object class methods, we will get compiler error as “This static method cannot hide the instance method from Object”. This is because it’s not allowed in java, since Object is the base class for all the classes and we can’t have one class level static method and another instance method with same signature.
  5. We can use java interface static methods to remove utility classes such as Collections and move all of it’s static methods to the corresponding interface, that would be easy to find and use.

Java Functional Interfaces

Before I conclude the post, I would like to provide a brief introduction to Functional interfaces. An interface with exactly one abstract method is known as Functional Interface.

A new annotation @FunctionalInterface has been introduced to mark an interface as Functional Interface. @FunctionalInterface annotation is a facility to avoid accidental addition of abstract methods in the functional interfaces. It’s optional but good practice to use it.

Functional interfaces are long awaited and much sought out feature of Java 8 because it enables us to use lambda expressions to instantiate them. A new package java.util.function with bunch of functional interfaces are added to provide target types for lambda expressions and method references. We will look into functional interfaces and lambda expressions in the future posts.

Resource Location:

  1. Java 8 Interface Changes – static method, default method



I believe what the interviewer was trying to get at was probably the difference between interface and implementation.

The interface - not a Java interface, but "interface" in more general terms - to a code module is, basically, the contract made with client code that uses the interface.

The implementation of a code module is the internal code that makes the module work. Often you can implement a particular interface in more than one different way, and even change the implementation without client code even being aware of the change.

A Java interface should only be used as an interface in the above generic sense, to define how the class behaves for the benefit of client code using the class, without specifying any implementation. Thus, an interface includes method signatures - the names, return types, and argument lists - for methods expected to be called by client code, and in principle should have plenty of Javadoc for each method describing what that method does. The most compelling reason for using an interface is if you plan to have multiple different implementations of the interface, perhaps selecting an implementation depending on deployment configuration.

A Java abstract class, in contrast, provides a partial implementation of the class, rather than having a primary purpose of specifying an interface. It should be used when multiple classes share code, but when the subclasses are also expected to provide part of the implementation. This permits the shared code to appear in only one place - the abstract class - while making it clear that parts of the implementation are not present in the abstract class and are expected to be provided by subclasses.




An interface consists of singleton variables (public static final) and public abstract methods. We normally prefer to use an interface in real time when we know what to do but don't know how to do it.

This concept can be better understood by example:

Consider a Payment class. Payment can be made in many ways, such as PayPal, credit card etc. So we normally take Payment as our interface which contains a makePayment() method and CreditCard and PayPal are the two implementation classes.

public interface Payment
{
    void makePayment();//by default it is a abstract method
}
public class PayPal implements Payment
{
    public void makePayment()
    {
        //some logic for PayPal payment
        //e.g. Paypal uses username and password for payment
    }
}
public class CreditCard implements Payment
{
    public void makePayment()
    {
        //some logic for CreditCard payment
        //e.g. CreditCard uses card number, date of expiry etc...
    }
}

In the above example CreditCard and PayPal are two implementation classes /strategies. An Interface also allows us the concept of multiple inheritance in Java which cannot be accomplished by an abstract class.

We choose an abstract class when there are some features for which we know what to do, and other features that we know how to perform.

Consider the following example:

public abstract class Burger
{
    public void packing()
    {
        //some logic for packing a burger
    }
    public abstract void price(); //price is different for different categories of burgers
}
public class VegBerger extends Burger
{
    public void price()
    {
        //set price for a veg burger.
    }
}
public class NonVegBerger extends Burger
{
    public void price()
    {
        //set price for a non-veg burger.
    }
}

If we add methods (concrete/abstract) in the future to a given abstract class, then the implementation class will not need a change its code. However, if we add methods in an interface in the future, we must add implementations to all classes that implemented that interface, otherwise compile time errors occur.

There are other differences but these are major ones which may have been what your interviewer expected . Hopefully this was helpful.




You choose Interface in Java to avoid the Diamond Problem in multiple inheritance.

If you want all of your methods to be implemented by your client you go for interface. It means you design the entire application at abstract.

You choose abstract class if you already know what is in common. For example Take an abstract class Car. At higher level you implement the common car methods like calculateRPM(). It is a common method and you let the client implement his own behavior like
calculateMaxSpeed() etc. Probably you would have explained by giving few real time examples which you have encountered in your day to day job.




Many junior developers make the mistake of thinking of interfaces, abstract and concrete classes as slight variations of the same thing, and choose one of them purely on technical grounds: Do I need multiple inheritance? Do I need some place to put common methods? Do I need to bother with something other than just a concrete class? This is wrong, and hidden in these questions is the main problem: "I". When you write code for yourself, by yourself, you rarely think of other present or future developers working on or with your code.

Interfaces and abstract classes, although apparently similar from a technical point of view, have completely different meanings and purposes.

Summary

  1. An interface defines a contract that some implementation will fulfill for you.

  2. An abstract class provides a default behavior that your implementation can reuse.

These two points above is what I'm looking for when interviewing, and is a compact enough summary. Read on for more details.

Alternative summary

  1. An interface is for defining public APIs
  2. An abstract class is for internal use, and for defining SPIs

By example

To put it differently: A concrete class does the actual work, in a very specific way. For example, an ArrayList uses a contiguous area of memory to store a list of objects in a compact manner which offers fast random access, iteration, and in-place changes, but is terrible at insertions, deletions, and occasionally even additions; meanwhile, a LinkedList uses double-linked nodes to store a list of objects, which instead offers fast iteration, in-place changes, and insertion/deletion/addition, but is terrible at random access. These two types of lists are optimized for different use cases, and it matters a lot how you're going to use them. When you're trying to squeeze performance out of a list that you're heavily interacting with, and when picking the type of list is up to you, you should carefully pick which one you're instantiating.

On the other hand, high level users of a list don't really care how it is actually implemented, and they should be insulated from these details. Let's imagine that Java didn't expose the List interface, but only had a concrete List class that's actually what LinkedList is right now. All Java developers would have tailored their code to fit the implementation details: avoid random access, add a cache to speed up access, or just reimplement ArrayList on their own, although it would be incompatible with all the other code that actually works with List only. That would be terrible... But now imagine that the Java masters actually realize that a linked list is terrible for most actual use cases, and decided to switch over to an array list for their only List class available. This would affect the performance of every Java program in the world, and people wouldn't be happy about it. And the main culprit is that implementation details were available, and the developers assumed that those details are a permanent contract that they can rely on. This is why it's important to hide implementation details, and only define an abstract contract. This is the purpose of an interface: define what kind of input a method accepts, and what kind of output is expected, without exposing all the guts that would tempt programmers to tweak their code to fit the internal details that might change with any future update.

An abstract class is in the middle between interfaces and concrete classes. It is supposed to help implementations share common or boring code. For example, AbstractCollection provides basic implementations for isEmpty based on size is 0, contains as iterate and compare, addAll as repeated add, and so on. This lets implementations focus on the crucial parts that differentiate between them: how to actually store and retrieve data.

Another perspective: APIs versus SPIs

Interfaces are low-cohesion gateways between different parts of code. They allow libraries to exist and evolve without breaking every library user when something changes internally. It's called Application Programming Interface, not Application Programming Classes. On a smaller scale, they also allow multiple developers to collaborate successfully on large scale projects, by separating different modules through well documented interfaces.

Abstract classes are high-cohesion helpers to be used when implementing an interface, assuming some level of implementation details. Alternatively, abstract classes are used for defining SPIs, Service Provider Interfaces.

The difference between an API and an SPI is subtle, but important: for an API, the focus is on who uses it, and for an SPI the focus is on who implements it.

Adding methods to an API is easy, all existing users of the API will still compile. Adding methods to an SPI is hard, since every service provider (concrete implementation) will have to implement the new methods. If interfaces are used to define an SPI, a provider will have to release a new version whenever the SPI contract changes. If abstract classes are used instead, new methods could either be defined in terms of existing abstract methods, or as empty throw not implemented exception stubs, which will at least allow an older version of a service implementation to still compile and run.

A note on Java 8 and default methods

Although Java 8 introduced default methods for interfaces, which makes the line between interfaces and abstract classes even blurrier, this wasn't so that implementations can reuse code, but to make it easier to change interfaces that serve both as an API and as an SPI (or are wrongly used for defining SPIs instead of abstract classes).

"Book knowledge"

The technical details provided in the OP's answer are considered "book knowledge" because this is usually the approach used in school and in most technology books about a language: what a thing is, not how to use it in practice, especially in large scale applications.

Here's an analogy: supposed the question was:

What is better to rent for prom night, a car or a hotel room?

The technical answer sounds like:

Well, in a car you can do it sooner, but in a hotel room you can do it more comfortably. On the other hand, the hotel room is in only one place, while in the car you can do it in more places, like, let's say you can go to the vista point for a nice view, or in a drive-in theater, or many other places, or even in more than one place. Also, the hotel room has a shower.

That is all true, but completely misses the points that they are two completely different things, and both can be used at the same time for different purposes, and the "doing it" aspect is not the most important thing about either of the two options. The answer lacks perspective, it shows an immature way of thinking, while correctly presenting true "facts".




What about thinking the following way:

  • A relationship between a class and an abstract class is of type "is-a"
  • A relationship between a class and an interface is of type "has-a"

So when you have an abstract class Mammals, a subclass Human, and an interface Driving, then you can say

  • each Human is-a Mammal
  • each Human has-a Driving (behavior)

My suggestion is that the book knowledge phrase indicates that he wanted to hear the semantic difference between both (like others here already suggested).




Abstract classes are not pure abstraction bcz its collection of concrete(implemented methods) as well as unimplemented methods. But Interfaces are pure abstraction bcz there are only unimplemented methods not concrete methods.

Why Abstract classes?

  1. If user want write common functionality for all objects.
  2. Abstract classes are best choice for reimplementation in future that to add more functionality without affecting of end user.

Why Interfaces?

  1. If user want to write different functionality that would be different functionality on objects.
  2. Interfaces are best choice that if not need to modify the requirements once interface has been published.



Related