What’s the difference between an interface and an abstract class in Java?

An interface is similar to a class in the following ways −

  • An interface can contain any number of methods.

  • An interface is written in a file with a .java extension, with the name of the interface matching the name of the file.

  • The byte code of an interface appears in a .class file.

  • Interfaces appear in packages, and their corresponding bytecode file must be in a directory structure that matches the package name.

However, an interface is different from a class in several ways, including −

  • You cannot instantiate an interface.

  • An interface does not contain any constructors.

  • All of the methods in an interface are abstract.

  • An interface cannot contain instance fields. The only fields that can appear in an interface must be declared both static and final.

  • An interface is not extended by a class; it is implemented by a class.

  • An interface can extend multiple interfaces.

     

Let's start:

    • Object/Behavior

      Abstract classes describe an object; Interfaces - Behavior

    • New Object

      Abstract classes cannot be used to create a new object (As well as an interface), all objects must instantiate from concrete classes (which may be inherited from an abstract class).

    • Inheritance

      Abstract classes are not enable multiple inheritance; but Interfaces enabling multiple type inheritance while guaranteeing single implementation inheritance.

      An interface can extend another interface in the same way that a class can extend another class. The extends keyword is used to extend an interface, and the child interface inherits the methods of the parent interface.

      A Java class can only extend one parent class. Multiple inheritance is not allowed. Interfaces are not classes, however, and an interface can extend more than one parent interface.

      The extends keyword is used once, and the parent interfaces are declared in a comma-separated list.

      public interface Hockey extends Sports, Event  

      An interface cannot extends or implement an abstract class

    • Methods

      An abstract class does not need any abstract methods; however, any class with an abstract method must be declared abstract. Abstract classes can implement private and protected methods.

      All methods of Interfaces are abstract (except static and default methods on interfaces from Java 8) and public. Interfaces, however, do not permit any method implementations, so from an implementation perspective, interfaces guarantee no implementation.

      package com.journaldev.java8.defaultmethod;
      
      public interface Interface1 {
      
      	void method1(String str);
      	
      	default void log(String str){
      		System.out.println("Hello::"+str);
      	}
      }
      

       

      Designing interfaces have always been a tough job because if we want to add additional methods in the interfaces, it will require change in all the implementing classes. As interface grows old, the number of classes implementing it might grow to an extent that it’s not possible to extend interfaces. That’s why when designing an application, most of the frameworks provide a base implementation class and then we extend it and override methods that are applicable for our application.

      Notice that log(String str) is the default method in the Interface1. Now when a class will implement Interface1, it is not mandatory to provide implementation for default methods of interface. This feature will help us in extending interfaces with additional methods, all we need is to provide a default implementation.

      In the case when a class implements both interfaces with default methods with the same name, compiler can’t decide which one to chose. Extending multiple interfaces are an integral part of Java, you will find it in the core java classes as well as in most of the enterprise application and frameworks. So to make sure, this problem won’t occur in interfaces, it’s made mandatory to provide implementation for common default methods of interfaces. So if a class is implementing both the above interfaces, it will have to provide implementation for log() method otherwise compiler will throw compile time error.

      Main things about 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.

       

      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 in case of poor implementation in implementation classes.

      in implementation classes. Let’s look into this with a simple example.

      package com.dev.java8.staticmethod;
      
      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.

      package com.journaldev.java8.staticmethod;
      
      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.

       

      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.

    • Constructor

      An abstract class may have a constructor as a ordinary Java class; but a interface cannot.

    • Constants / Varables

      An interface can only define public static final constants. An interface cannot define instance variables.

      An abstract class can define both static and instance constants (final). An abstract class can define instance variables

       

       

      Abstract Classes An abstract class can never be instantiated. Its sole purpose, mission in life, raison d'être, is to be extended (subclassed). (Note, how- ever, that you can compile and execute an abstract class, as long as you don't try to make an instance of it.) Why make a class if you can't make objects out of it? Because the class might be just too, well, abstract. For example, imagine you have

      a class Car that has generic methods common to all vehicles. But you don't want anyone actually creating a generic, abstract Car object. How would they initialize its state? What color would it be? How many seats? Horsepower? All-wheel drive? Or more importantly, how would it behave? In other words, how would the methods be implemented? 

 abstract class Car {
     private double price;
     private String model;
     private String year;
     public abstract void goFast();
     public abstract void goUpHill();
     public abstract void impressNeighbors();
     // Additional, important, and serious code goes here
}

Notice that the methods marked abstract end in a semicolon rather than curly braces.

 

Look for questions with a method declaration that ends with a semicolon, rather than curly braces. If the method is in a class—as opposed to an interface—then both the method and the class must be marked abstract. You might get a question that asks how you could fix a code sample that includes a method ending in a semicolon, but without an abstract modifier on the class or method. In that case, you could either mark the method and class abstract, or change the semicolon to code (like a curly brace pair). Remember, if you change a method from abstract to nonabstract, don't forget to change the semicolon at the end of the method declaration into a curly brace pair!

If even a single method is abstract, the whole class must be declared abstract. One abstract method spoils the whole bunch. You can, however, put nonabstract methods in an abstract class. You can't mark a class as both abstract and final. They have nearly opposite meanings. An abstract class must be subclassed, whereas a final class must not be subclassed. If you see this combination of abstract and final modifiers, used for a class or method declaration, the code will not compile.

 When you create an interface, you're defining a contract for what a class can do, without saying anything about how the class will do it. An interface is a contract. You could write an interface Bounceable, for example, that says in effect, "This is the Bounceable interface. Any class type that implements this interface must agree to write the code for the bounce() and setBounceFactor() methods."

 But while an abstract class can define both abstract and non-abstract methods, an interface can have only abstract methods. Another way interfaces differ from abstract classes is that interfaces have very little flexibility in how the methods and variables defined in the interface are declared. These rules are strict:

  • All interface methods are implicitly public and abstract. In other words, you do not need to actually type the public or abstract modifiers in the method declaration, but the method is still always public and abstract.

  • All variables defined in an interface must be public, static, and final— in other words, interfaces can declare only constants, not instance variables.

     
  • Interface methods must not be static (except Java 8).

Because interface methods are abstract, they cannot be marked final, 

strictfp, or native. (More on these modifiers later.)
  • An interface can extend one or more other interfaces.
  • An interface cannot extend anything but another interface.
  • An interface cannot implement another interface or class.
  • An interface must be declared with the keyword interface.
  • Interface types can be used polymorphically 
  •  

     

    1. The following is a legal interface declaration:

        public abstract interface Rollable { }

Typing in the abstract modifier is considered redundant; interfaces are implicitly abstract whether you type abstract or not. You just need to know that both of these declarations are legal, and functionally identical:

  public abstract interface Rollable { }
  public interface Rollable { }

The public modifier is required if you want the interface to have public rather than default access.

We've looked at the interface declaration but now we'll look closely at the methods within an interface:

  public interface Bounceable {
      public abstract void bounce();
      public abstract void setBounceFactor(int bf);

}

Typing in the public and abstract modifiers on the methods is redundant, though, since all interface methods are implicitly public and abstract. Given that rule, you can see that the following code is exactly equivalent to the preceding interface:

  public interface Bounceable {
        void bounce();                 // No modifiers
        void setBounceFactor(int bf);  // No modifiers

 

Because interface constants are defined in an interface, they don't have to be declared as public, static, or final. They must be public, static, and final, but you don't have to actually declare them that way.

Just as interface methods are always public and abstract whether you say so in the code or not, any variable defined in an interface must be—and implicitly is—a public constant.