What is Abstraction in Java with Examples & Its Uses

What is Abstraction in Java with Examples & Its Uses

13 Sep 2024
Intermediate
9.29K Views
32 min read
Learn with an interactive course and practical hands-on labs

Java Online Course Free with Certificate (2024)

Abstraction in Java

Abstraction is a fundamental concept in Java's object-oriented programming. It enables you to hide complex implementation details and display only the most essential features of an object. This provides a more explicit and simpler interface to the outside world, making the system easier to understand and manage.

In this Java Tutorial, we will discuss Abstraction in Java with proper illustrations. We will explain abstract classes, abstract methods, and interfaces, the difference between abstract classes and interfaces, and the pros and cons of abstraction with examples. So, let's start by discussing "What is Abstraction?"

Fast-track your tech career with our Java Full Stack Developer Course —start learning today!

Before moving further, you need to be thorough with the following concepts; otherwise, you won't understand this topic completely:
Read More: Top 50 Java Interview Questions For Freshers

What is Abstraction in Java?

  • Abstraction in Java is the technique of hiding implementation details and displaying only functionality to the user. 
  • It reduces complexity and allows the programmer to concentrate on the object's functionality rather than its implementation.
  • It enables developers to create complex applications without having to worry about low-level details such as Java data types and variables, memory management, and platform independence.

Abstraction in Java is performed in two ways:

  1. Abstract Classes
  2. Interfaces

1. Abstract Class in Java

  • An abstract class is a class that has been declared abstract. It might include both abstract and non-abstract approaches. 
  • It needs to be expanded and its method implemented. 
  • It cannot be instantiated. It can have both constructors and static methods. 
  • Final methods can prevent subclasses from changing their methods' contents.

Rules for Java Abstract Class

  • An abstract class must be declared with the abstract keyword.
  • It can have abstract and non-abstract methods.
  • It cannot be instantiated.
  • It can have final methods.
  • It can also have constructors and static methods.

Abstract Method in Java

  • In Java, an abstract method is declared but not implemented. It is specified within an abstract class and must be overridden by its subclasses. 
  • An abstract method is intended to be a placeholder that enforces specific behavior in subclasses. 
  • It serves a useful purpose when the desired behavior of the method should remain consistent while allowing different implementations within different classes.
Read More: Java Developer Salary In India

When should abstract classes and abstract methods be used?

  • Use abstract classes to create a template for subclasses with similar features and behaviors.
  • Declare abstract methods to outline the functionality that subclasses must implement.
  • Use abstract classes to provide limited implementations (default behavior) for specific methods.
  • Unlike interfaces, abstract classes provide more control over member access (protected fields).
  • Use abstract classes when creating a class hierarchy with closely related subclasses.

Algorithm to Implement Abstraction in Java

  1. Identify the classes or interfaces that will form the abstraction.
  2. Create an abstract class or interface to describe common behaviors and properties among these classes.
  3. Define abstract methods in the abstract class or interface that do not require implementation details.
  4. Use concrete classes to extend abstract classes or implement interfaces.
  5. Override abstract methods in concrete classes for specific implementation.
  6. Use concrete classes to implement program logic.

Example of Java Abstraction Using Abstract Classes and Abstract Methods

// Define the abstract class
abstract class Animal {
    // Abstract method (does not have a body)
    public abstract void makeSound();
    
    // Regular method
    public void sleep() {
        System.out.println("Zzz...");
    }
}

// Subclass (inherited from Animal)
class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Woof");
    }
}

// Subclass (inherited from Animal)
class Cat extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Meow");
    }
}

// Use the abstract class
class Main {
    public static void main(String[] args) {
        Animal dog = new Dog();
        Animal cat = new Cat();
        
        dog.makeSound(); // Output: Woof
        dog.sleep();     // Output: Zzz...
        
        cat.makeSound(); // Output: Meow
        cat.sleep();     // Output: Zzz...
    }
}

In this example, Animal is an abstract class with one abstract method, makeSound, and one regular method, sleep. Dog & Cat are subclasses that extend Animal and implement the makeSound function. In the Main class, Dog and Cat instances are created, and their respective methods are called. Animals cannot be instantiated directly; however, their subclasses can be utilized to generate objects.

Output

Woof
Zzz...
Meow
Zzz...

2. Interface in Java

  • Interfaces are another way of implementing abstraction in Java. The fundamental distinction is that using interfaces allows us to achieve 100% abstraction in Java classes
  • Interfaces, whether in Java or another language, contain both methods and variables but lack a method body. In addition to abstraction

Interfaces can be used to implement interfaces in Java.

  • As with the abstract class, it cannot be instantiated.
  • Since Java 8, we can include default and static methods in interfaces.
  • Since Java 9, we can include private methods in interfaces.

Syntax of Interface Declaration

The interface keyword is used to declare a new interface. It provides an entire abstraction, which implies that all methods in an interface are defined with an empty body, and all fields are public, static, and final by definition. A class that implements an interface must include all of the methods specified in the interface.


interface {  
      
    // declare constant fields  
    // declare methods that abstract   
    // by default.  
} 

Why do classes implement interfaces?

  • It is used to accomplish complete abstraction. Because Java does not permit multiple inheritances for classes, utilizing an interface allows for multiple inheritances
  • Any class can only extend one class, but it can implement an endless number of interfaces. It is also used to create loose coupling.
Read More: Multiple Inheritance in Java

Which classes should implement the interface?

  • If a class includes basic business logic and is the only implementation of an interface, build a concrete class instead.
  • Implement details like persistence, REST calls, and UI on an "external" layer using an interface.

Example of Java Interface


public class Main {    
    // Define the Vehicle interface
    public interface Vehicle {
        // Abstract method to start the vehicle
        void start();
        
        // Abstract method to stop the vehicle
        void stop();
    }

    // Implement the Vehicle interface in the Car class
    public static class Car implements Vehicle {
        @Override
        public void start() {
            System.out.println("The car is starting.");
        }

        @Override
        public void stop() {
            System.out.println("The car is stopping.");
        }
    }

    public static void main(String[] args) {
        // Create an instance of Car
        Vehicle myCar = new Car();

        // Call methods defined in the interface
        myCar.start();  // Output: The car is starting.
        myCar.stop();   // Output: The car is stopping.
    }
}

The Vehicle interface provides two methods: start() and stop(), which every implementing class must implement. The Car class implements these methods in specific ways. The main() method creates a car object as a vehicle and calls it the start() and stop() methods.

Output

The car is starting.
The car is stopping.

Java 8 Default Method in Interface

Since Java 8, we can include method bodies in interfaces. But we need to make it the default method.

Example of Default Method in Java Interface


class Main {

    // Define the Shape interface
    public interface Shape {
        // Abstract methods to be implemented by any class that implements this interface
        double getArea();
        double getPerimeter();

        // Default method to describe the shape
        default void describe() {
            System.out.println("This is a shape.");
        }
    }

    // Implement the Shape interface in the Square class
    public static class Square implements Shape {
        private double side;

        public Square(double side) {
            this.side = side;
        }

        @Override
        public double getArea() {
            return side * side;
        }

        @Override
        public double getPerimeter() {
            return 4 * side;
        }
    }

    // Implement the Shape interface in the Triangle class
    public static class Triangle implements Shape {
        private double a, b, c;  // sides of the triangle

        public Triangle(double a, double b, double c) {
            this.a = a;
            this.b = b;
            this.c = c;
        }

        @Override
        public double getArea() {
            double s = (a + b + c) / 2;
            return Math.sqrt(s * (s - a) * (s - b) * (s - c));
        }

        @Override
        public double getPerimeter() {
            return a + b + c;
        }
    }

    public static void main(String[] args) {
        // Create instances of Square and Triangle
        Shape mySquare = new Square(4.0);
        Shape myTriangle = new Triangle(3.0, 4.0, 5.0);

        // Call the abstract methods defined in the interface
        System.out.println("Square Area: " + mySquare.getArea());  // Output: Square Area: 16.0
        System.out.println("Square Perimeter: " + mySquare.getPerimeter());  // Output: Square Perimeter: 16.0
        mySquare.describe();  // Output: This is a shape.

        System.out.println("Triangle Area: " + myTriangle.getArea());  // Output: Triangle Area: 6.0
        System.out.println("Triangle Perimeter: " + myTriangle.getPerimeter());  // Output: Triangle Perimeter: 12.0
        myTriangle.describe();  // Output: This is a shape.
    }
}

This Java code creates an interface Shape with getArea(), getPerimeter(), and a default describe() function. It then uses this interface in the Square and Triangle classes to determine the area and perimeter. In main(), instances of Square and Triangle are created, their functions are invoked to compute geometric characteristics, and the describe() method returns a generic shape description for each.

Output

Square Area: 16.0
Square Perimeter: 16.0
This is a shape.
Triangle Area: 6.0
Triangle Perimeter: 12.0
This is a shape.

Java 8 Static Method in Interface

Since Java 8, we can include static methods in interfaces.

Example of Static Method in Java Interface


class Main {

    // Define the Operation interface
    public interface Operation {
        // Abstract method to perform an operation
        double execute(double a, double b);

        // Static method to provide a default calculation for addition
        static double add(double a, double b) {
            return a + b;
        }
    }

    // Implement the Operation interface in the Addition class
    public static class Addition implements Operation {
        @Override
        public double execute(double a, double b) {
            return a + b;
        }
    }

    // Implement the Operation interface in the Multiplication class
    public static class Multiplication implements Operation {
        @Override
        public double execute(double a, double b) {
            return a * b;
        }
    }

    public static void main(String[] args) {
        // Create instances of Addition and Multiplication
        Operation addition = new Addition();
        Operation multiplication = new Multiplication();

        // Call the execute method defined in the interface
        System.out.println("Addition Result: " + addition.execute(5, 3));          // Output: Addition Result: 8.0
        System.out.println("Multiplication Result: " + multiplication.execute(5, 3)); // Output: Multiplication Result: 15.0

        // Call the static method from the Operation interface
        System.out.println("Static Addition Result: " + Operation.add(7, 2));   // Output: Static Addition Result: 9.0
    }
}

This Java code creates an Operation interface that includes an execute() method for operations and a static add() addition method. The Addition class uses the Operation interface to conduct addition, whereas the Multiplication class uses it to accomplish multiplication.

The main() method creates instances of Addition and Multiplication and calls their execute() methods to demonstrate their respective operations. The static add() method is directly from the Operation interface.

Output

Addition Result: 8.0
Multiplication Result: 15.0
Static Addition Result: 9.0

Why do we use an Interface in Java?

Here are some reasons why we use an interface in Java:

  • To achieve abstraction: Interfaces can be used to achieve abstraction, which is an essential aspect of object-oriented programming. By defining an interface, anyone can separate the implementation of a class from its behavior.
  • To provide multiple inheritances: Java doesn't support multiple inheritances of classes, but the developer can achieve a similar effect by using interfaces. A class can implement multiple interfaces, which allows it to inherit the behavior of all the interfaces it implements.
  • To define constants: Interfaces can be used to define constants that are shared by multiple classes.
  • To define callbacks: Interfaces can be used to define callbacks, which are methods that are called by an object in response to an event.
  • To achieve polymorphism: Interfaces can be used to achieve polymorphism, which is the ability of objects of different classes to be used interchangeably. By defining a standard interface, the programmer can write code that works with any object that implements that interface.

Abstract Class Vs. Interface in Java

FeatureAbstract Class Interface
Method TypesIt can have abstract and non-abstract methods.It can only have abstract methods (except for Java 8's default and static methods)
Multiple InheritanceNot supportedSupported
Variable TypesIt can have final, non-final, static, and non-static variables.It can only have static and final variables (implicitly)
ImplementationCan provide an implementation for interfacesCannot provide an implementation for abstract classes
Declaration Keywordabstractinterface
InheritanceCan extend one class and implement multiple interfacesCan only extend other interfaces
Extending/Implementing KeywordExtends for class inheritance, implements for interface implementationImplements for interface implementation
Member Access ModifiersCan have private, protected, and public membersMembers are public by default
Examplepublic abstract class Shape { public abstract void draw(); }public interface Drawable { void draw(); }

Diagram for Abstract Class Vs. Interface in Java

Example Illustrating Abstract Class and Interface in a Java Program

Let's look at a basic example that uses both an interface and an abstract class.


class Main {

    // Define the Shape interface
    public interface Shape {
        double getArea();
        double getPerimeter();
    }

    // Define an abstract class that implements the Shape interface
    public static abstract class AbstractShape implements Shape {
        private String color;

        public AbstractShape(String color) {
            this.color = color;
        }

        public String getColor() {
            return color;
        }

        public void showColor() {
            System.out.println("Color: " + color);
        }

        public abstract void draw();
    }

    // Circle class implementing Shape and extending AbstractShape
    public static class Circle extends AbstractShape {
        private double radius;

        public Circle(String color, double radius) {
            super(color);
            this.radius = radius;
        }

        @Override
        public double getArea() {
            return Math.PI * radius * radius;
        }

        @Override
        public double getPerimeter() {
            return 2 * Math.PI * radius;
        }

        @Override
        public void draw() {
            System.out.println("Drawing a circle.");
        }
    }

    // Rectangle class implementing Shape and extending AbstractShape
    public static class Rectangle extends AbstractShape {
        private double width, height;

        public Rectangle(String color, double width, double height) {
            super(color);
            this.width = width;
            this.height = height;
        }

        @Override
        public double getArea() {
            return width * height;
        }

        @Override
        public double getPerimeter() {
            return 2 * (width + height);
        }

        @Override
        public void draw() {
            System.out.println("Drawing a rectangle.");
        }
    }

    public static void main(String[] args) {
        Shape circle = new Circle("red", 5.0);
        Shape rectangle = new Rectangle("blue", 4.0, 6.0);

        System.out.println("Circle Area: " + circle.getArea());
        System.out.println("Circle Perimeter: " + circle.getPerimeter());
        ((AbstractShape) circle).showColor();
        ((AbstractShape) circle).draw();

        System.out.println("Rectangle Area: " + rectangle.getArea());
        System.out.println("Rectangle Perimeter: " + rectangle.getPerimeter());
        ((AbstractShape) rectangle).showColor();
        ((AbstractShape) rectangle).draw();
    }
}

The Java code includes a Shape interface with methods for area and perimeter calculation. An AbstractShape abstract class implements Shape, includes a color field with showColor(), and declares draw() abstract. Circle and Rectangle expand AbstractShape by defining area, perimeter, and draw methods. In main(), Circle and Rectangle objects demonstrate method calls and interface polymorphism.

Output

Circle Area: 78.53981633974483
Circle Perimeter: 31.41592653589793
Color: red
Drawing a circle.
Rectangle Area: 24.0
Rectangle Perimeter: 20.0
Color: blue
Drawing a rectangle.

Advantages of Abstraction in Java

  • It simplifies the way we observe things.
  • Reduces code duplication and promotes reusability.
  • Improves application or program security by limiting user access to only necessary information.
  • It promotes application maintainability.
  • Improves the application's modularity.
  • We can make changes to our internal system without affecting end-users, making enhancements much more accessible.
  • Promotes code reuse and maintainability.
  • Minimises implementation details and only provides necessary information.
  • Ensures a clear and straightforward user interface.
  • Improves security by restricting access to internal class information.

Disadvantages of Abstraction in Java

  • Abstraction may prevent understanding of the system's functionality.
  • Improper use may result in additional complexity. This may limit implementation flexibility.
  • Improper use of abstraction can increase code complexity, resulting in longer development times and effort.
  • Unfamiliarity with abstraction layers and implementation specifics might hinder code understanding and debugging.
  • Excessive abstraction might lead to slower performance as it adds layers of code and indirections.

Encapsulation vs Data Abstraction

EncapsulationData Abstraction
They combine methods and data into one class and limit access to data members.By creating classes based on crucial traits and behaviors, complicated systems can be made simpler.
Control over who has access to private data.Exposing key functionalities while obscuring implementation details.
Access modifiers (such as private, protected, and public) are used to do this.Emphasizes the development of abstract methods and high-level interfaces.
Giving regulated access helps maintain the security and integrity of data.Reducing complexity, making it easier to maintain, and offering a straightforward interface.
Public getter/setter methods and private fields are used to access and change data.Developing abstract classes or interfaces that have abstract methods that subclasses can implement.
Also, read the related interview articles like:
Summary

Java data abstraction improves modularity, encourages code reuse, simplifies complex implementations, and fortifies security by restricting access to essential information. It prioritizes functionality above implementation details, making software systems more straightforward and manageable.

Understanding how to use abstraction through abstract classes or interfaces allows you to create more flexible, scalable programs that are easier to maintain and modify. You can consider enrolling in our Java Full Stack Course to implement what you learned about Abstraction in Java.

FAQs

 Abstract classes in Java define a base class with common properties and methods that can be inherited by subclasses while preventing the instantiation of the base class itself. They can also contain abstract methods that must be implemented by any concrete subclass. 

 An abstract class is required to provide a common base with shared functionality and define abstract methods that must be implemented by derived classes. This ensures a consistent interface while allowing specific implementations. 

Code simplicity, enhanced maintainability, and explicit interfaces are benefits of abstraction.

 Abstraction in programming hides the complex implementation details and shows only the essential features of an object. Encapsulation bundles the data and methods operating on the data into a single unit (class) and restricts access to some of the object's components. 
Share Article
About Author
Shailendra Chauhan (Microsoft MVP, Founder & CEO at Scholarhat by DotNetTricks)

Shailendra Chauhan is the Founder and CEO at ScholarHat by DotNetTricks which is a brand when it comes to e-Learning. He provides training and consultation over an array of technologies like Cloud, .NET, Angular, React, Node, Microservices, Containers and Mobile Apps development. He has been awarded Microsoft MVP 9th time in a row (2016-2024). He has changed many lives with his writings and unique training programs. He has a number of most sought-after books to his name which has helped job aspirants in cracking tough interviews with ease.
Accept cookies & close this