Abstract Classes and Interfaces

All about Interfaces and Abstract classes In Java:

As we have discussed and understood this earlier, Java is an object-oriented programming language and a Class is like an object constructor, or say a “blueprint” for creating objects [i.e.group of similar objects]. So coming down to understanding why classes are needed in Java? Putting it short, classes help us take all the properties and behaviours of an object in our program, and combines them into a single template. Having said that, a class in Java is simply a template for creating objects of similar attributes and behaviour.

Hi Comrades,

To begin with let us know what are interfaces and abstract classes? User-defined classes are classes that the user defines and manipulates in the real-time programming environment and further this user-defined class is broken down into three types:

  • Concrete classes
  • Abstract classes
  • Interfaces

How are abstract classes different from the concrete classes in Java?

As we know that a concrete class is a class that has an implementation for all of its methods. They cannot have any unimplemented methods within them. They can also extend an abstract class or implement an interface as long as it implements all their methods. It is a complete class and can be instantiated. Hence we can say that a concrete class is a subclass of an abstract class, which implements all its abstract methods. Abstract methods are the methods that do not have a body i.e.they do not have any method definitions written in them, but they can have static fields and static method, like other classes. We cannot instantiate abstract classes using “new” keyword. Hence we can define an abstract class as a class whose purpose is to function as base class which can be extended by subclasses to create a full implementation of the abstract methods. An abstract class allows you to create functionality that subclasses can implement or override.

eg:Declaring an abstract class:
public abstract class Vehicle{
}
eg: we cannot instantiate it:
Vehicle myVehicleObject = new Vehicle();
we will get here an compile time error stating " you cannot instantiate Vehicle"
eg: abstract methods:
public abstract class Vehicle{
public abstract void applyBreak();
}
the abstract method has no implementation written in it. their implementations are overridden by the subclasses.

Understanding the basic purpose of having an abstract class could be, We can opt for creating an abstract class to maintain the forward compatibility of the code. Having said this, once a client uses an interface , we cannot add further enhancements to it , but if they make use of abstract class, we can still add behaviours without breaking any existing code.We can make a choice o f using an abstract class for an inheritance concept as it provides us with the common base class implementations to the derived [sub classes] classes.

Explaining this with a fine example, let us consider we have to make a system which does some preprocessing, some action and some postprocessing. So here we can have implementation of preprocessing and postprocessing written in abstract class itself, but the implementation of action can be written in any of the subclasses.

eg:
public abstract class MakeSystem{
public void preprocessing(){
// implementation to be written in this class itself
}

public void postprocessing(){
//implementation to be written in this class itself
}
public abstract void action();
// implementation to be written in any of the sub classes which would extend this abstract class.
}

After understanding the above points we can say, that abstract classes reduces the complexity of code w.r.t viewing of code, reduces duplication of code there by increasing the reusability and increases the security of any application / system i.e. only the relevant part of a code to be seen to the user.

How are interfaces different from abstract classes in Java?

Moving ahead to understanding of interfaces; As we know by now what is an abstract class, I shall frame what an interface is in context to abstract class for you. An interface is a fully abstract class, which means; as an abstract class has both an abstract and non-abstract methods, interfaces has only abstract methods [ from Java 8 onwards… interfaces do have default methods and from Java 9 onwards it was introduced with private methods as well]. Default methods are those methods of an interface which holds an implementation within their body. So why the default methods were introduced has a very generic explanation to it, previously in Java, when we had to add any method to an interface, the problem we faced were, if we added any new method to the interface then all the classes implementing the interface had to declare and define the body of the method within their classes. To resolve this, Java came up with concept of Default methods. Default interfaces also adds on a little complexity to the concept of interface inheritance. While it is normally possible for a class to implement multiple interfaces even if interfaces contains methods with same name and signature. This would not be possible if one or more of these methods are default methods. In other words, if two interfaces contain methods with same and same signature and one interface declares this method as default; a class cannot automatically implement both these interfaces. In this situation the Java compiler requires that the class implementing the interfaces explicitly implements the method which causes the problem; that way there is no doubt about which implementation the class will have. The implementation in the class takes the precedence over any default implementation. Java 8 had yet another concept introduced newly w.r.t. Interfaces; the feature to include static methods within an interface. So in order to use these static methods of an interface we will need a reference of the interface just like we do of classes’.

eg:
interface Polygon{
method(){...}
}
Polygon.method();

Similar to that of an abstract class we cannot create objects of an interface as well. Hence to use an interface, a class must implement the interface using keyword “implements”.

eg:
interface polygon{
void getArea(int length, int breadth);
}
class Rectangle implements polygon{public void getArea(int length, int breadth){
System.out.println("Area of rectangle is :(length* breadth)");
}
public static void main(String[] args){
Rectangle r = new Rectangle();
r.getArea(3,5);
}
}o/p : Area of rectangle is : 15

Similar to any class, an interface can extend other interfaces using the keyword “extends”. Similar to that of an abstract class, interfaces helps us achieve abstraction, provides specifications i.e. a class that implements it must follow.

Note: All the methods in an interface are implicitly public and fields[variables] are public static final.

Java 8 has also introduced a concept of Functional Interfaces, it is an interface that contains only one abstract method in it. This interface can also contain default and static methods in them but must have only one abstract method in it.Also called as Single Abstract Method interfaces (SAM Interfaces).

eg:
@FunctionalInterface
interface MyFunctionalInterface{
public void execute();
}

Functional Interfaces are implemented by lambda expressions[ we will be covering this in a further article]. Functional Interfaces are denoted by annotation @FunctionalInterface

eg:

MyFunctionalInterface lambda =() -> {
System.out.println(" am an implementation to abstract method in functional interface");
}

In Java 8 there are 4 main functional interfaces introduced which could be used in different scenarios.

  • Consumer
  • Predicate
  • Function
  • Supplier

Among the above four interfaces, the first three interfaces also have extensions: Consumer — BiConsumer; Predicate — BiPredicate; Function — BiFunction, UnaryOperator, BinaryOperator.

  • Consumer: The consumer interface accepts only one argument but there is no return value.
@FunctionalInterface
public interface Consumer<T> {
void accept(T t)
}

The extension of the Consumer which is BiConsumer accepts two arguments and return nothing.

@FunctionalInterface
public interface BiConsumer<T, U> {
void accept(T t, U u)
}
  • Predicate: Predicate will accept one argument, do some processing and then return boolean. Instead of one argument BiPredicate will accept two arguments and return nothing.
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t)
}
  • Function: This interface accepts one argument and return a value after the required processing. The BiFunction is similar to Function except it accepts two inputs. Another two interfaces are UnaryOperator and BinaryOperator which extends the Function and BiFunction respectively.
@FunctionalInterface
public interface Function<T , R> {
R apply(T t)
}
  • Supplier: Supplier functional interface does not accept any input rather return single output.
@FunctionalInterface
public interface Supplier<T> {
T get()
}

Hope this article helped you bringing up a clarity to the concept of Interfaces and abstract classes in Java.

Until next time…

Peace Out!

Rupam Pawan Jha

Software Development Engineer | Java | Object Oriented Programming | Multi threading | Data Structures and Algorithms | Design Patterns

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store