Abstraction in Java

Abstraction is a concept to handle complexity by hiding unnecessary details from the user. That enables the user to implement more complex logic on top of the provided abstraction without understanding or even thinking about all the hidden complexity.

Abstract Design

Abstract

In programming, we apply the same meaning of abstraction by making classes not associated with any specific instance. In Java, abstraction is achieved using abstract classes and interfaces.

abstract classes

Abstraction is done when we need to only inherit from a certain class, but do not need to instantiate objects of that class. In such a case the base class can be regarded as "incomplete". Such classes are known as an "abstract class".


Here some important points about abstract class :

  1. An abstract class cannot be instantiated; it means the object of that class cannot be created.
  2. Once a class having the abstract keyword in some of its methods (or all) is known as an abstract class.
  3. The abstract method of the abstract class has no implementation.
  4. An abstract class holds the methods but the actual implementation of those methods is made in subclass.


Let's check codes example below:

Animal.java
public abstract class Animal {
    
    public abstract void sound();
    
    public void getSpecies() {
        System.out.println("Species: " + this.getClass().getSimpleName());
    }
}
                    

Cat.java
public class Cat extends Animal {
    
    public void sound() {  
        System.out.println("Cat sound");  
    }
}
                    

We have 2 methods in the Animal Class, the method sound() has no implementation; that is why it is being declared as "abstract" while the method getSpecies() has its implementation so not abstract. Since Animal class has one abstract method, the class must declared as "abstract".
In the subclass (Cat class) method sound() has implementation. Since the method is complete, it's depend on the design if the class is complete and can be instantiate or can mark it as abstract to prevent instantiation and need to extends in subclass.

More in Abstract Class in Java.

interfaces

interface is used to achieve abstraction and multiple inheritance in Java. An interface can have methods and variables just like the class but the methods declared in interface are by default abstract*. Also, the variables declared in an interface are public, static & final by default*.

Eatable.java
public interface Eatable {
 
    void diet();
}
                    

Dog.java
public class Dog extends Animal implements Eatable {
    
    public void sound() {  
        System.out.println("Dog sound");
    }
    
    public void diet() {
        // Please don't argue
        System.out.println("Dog is an omnivore");
    }    
}
                    

We have one "abstract" method in Eatable interface, method diet(). The derived class (Dog class) implements Eatable and implement diet() method (concrete implementation with body). In the same time, class Dog also extends Animal class, so Dog class (optionally) can implement method sound() or choose to be abstract.

More in Interfaces in Java.

abstract vs interface


When To Use Abstract classes

abstract class, in provides more structure. It usually defines some default implementations and provides some flow useful for a full implementation. What the programmer need is to extend that class, and provide (more) specific implementation. The catch is, code using it must use your class as the base, and Java only allow one base class

When To Use Interfaces

In contrast, a derived class is allowed to implements multiple interface. An interface allows somebody to start from scratch to implement your interface or implement your interface in some other code whose original or primary purpose was quite different from your interface. The programmer is fully in control for their interpretation and implementation of the interface. The disadvantage is every method in the interface must be implemented and must be public.

Check Abstract Class vs Interface article.

Use Both

of course the programmer can use both. Subclass can be extended from one abstract base class to ensure the structure, but in the same time can implements multiple interface.

But be aware, one of the common problem in the OOP is overdesign. When doing object oriented design there are a couple of forces we need to balance. Most of OO design is about reducing and handling complexity. So if what we get is over-complexity design, and not otherwise (reducing complexity) , we're doing it wrong.