Abstraction in Java

Mohit  UpadhyayMohit Upadhyay
6 min read

On Day 11, we will explore Abstraction, one of the fundamental concepts of Object-Oriented Programming (OOPs) in Java. Abstraction allows us to focus on the essential qualities of an object, hiding unnecessary details. It simplifies complex reality by modeling classes based on the relevant attributes and behaviors.


1. What is Abstraction?

Abstraction in Java is a process of hiding the implementation details from the user and only providing the essential information. It is used to reduce complexity and make the application more understandable and easier to maintain.

  • In abstraction, we focus on "what" an object does rather than "how" it does it.

  • It allows developers to work at a higher level of thinking, focusing on the functionality while ignoring the underlying complexity.

For example, when you use a car, you don't need to understand the intricate details of how the engine works. You just need to know how to drive it.


2. How is Abstraction Achieved in Java?

Abstraction in Java can be achieved using two mechanisms:

  1. Abstract classes

  2. Interfaces

A. Abstract Classes

An abstract class in Java is a class that cannot be instantiated on its own. It can have both abstract methods (methods without a body) and concrete methods (methods with a body). Abstract classes allow you to define a common structure for related classes while forcing subclasses to implement specific behaviors.

Syntax for an Abstract Class:
abstract class Vehicle {
    // Abstract method (no implementation)
    abstract void start();

    // Concrete method (with implementation)
    void stop() {
        System.out.println("Vehicle has stopped.");
    }
}
Example of Abstract Class:
// Abstract class
abstract class Animal {
    // Abstract method
    abstract void sound();

    // Concrete method
    void sleep() {
        System.out.println("This animal is sleeping.");
    }
}

// Subclass that implements the abstract method
class Dog extends Animal {
    @Override
    void sound() {
        System.out.println("The dog barks.");
    }
}

class Cat extends Animal {
    @Override
    void sound() {
        System.out.println("The cat meows.");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal dog = new Dog();
        dog.sound();  // Calls Dog's sound method
        dog.sleep();  // Calls the concrete sleep method from Animal

        Animal cat = new Cat();
        cat.sound();  // Calls Cat's sound method
        cat.sleep();  // Calls the concrete sleep method from Animal
    }
}

Explanation:

  • The Animal class is abstract, and it contains an abstract method sound() that must be implemented by subclasses (Dog and Cat).

  • The sleep() method is a concrete method, which can be used by any subclass.

  • The Dog and Cat classes provide their own implementations of the sound() method, demonstrating how abstraction works.

B. Interfaces

An interface in Java is a blueprint for a class. It can contain abstract methods (in earlier versions of Java) and default or static methods (in newer versions). Interfaces are used to define common behavior that multiple classes can implement, even if they belong to different hierarchies.

Syntax for an Interface:
interface Vehicle {
    void start(); // Abstract method

    // Default method (introduced in Java 8)
    default void stop() {
        System.out.println("Vehicle has stopped.");
    }
}
Example of Interface:
// Interface
interface Animal {
    void sound();  // Abstract method
}

// Implementing the interface
class Dog implements Animal {
    @Override
    public void sound() {
        System.out.println("The dog barks.");
    }
}

class Cat implements Animal {
    @Override
    public void sound() {
        System.out.println("The cat meows.");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal dog = new Dog();
        dog.sound();  // Calls Dog's implementation

        Animal cat = new Cat();
        cat.sound();  // Calls Cat's implementation
    }
}

Explanation:

  • The Animal interface declares the sound() method, which is implemented by both the Dog and Cat classes.

  • By using interfaces, you can enforce a common contract that all implementing classes must follow, promoting loose coupling.


3. Key Differences Between Abstract Classes and Interfaces

Abstract ClassInterface
Can have both abstract and concrete methods.Can only have abstract methods (before Java 8).
Can have fields and constructors.Cannot have fields or constructors (until Java 9).
Supports inheritance.Supports multiple inheritance (a class can implement multiple interfaces).
Used when classes are closely related.Used when classes are not necessarily related but need to share a common contract.

4. Advantages of Abstraction

  • Reduces Complexity: By focusing on essential features and hiding irrelevant details, abstraction simplifies the programming process.

  • Improves Maintainability: Since the implementation details are hidden, changes to the underlying code do not affect the abstract layer, making it easier to maintain.

  • Encourages Reusability: Abstract classes and interfaces allow for code reusability, as different classes can share a common structure or behavior.

  • Supports Encapsulation: Abstraction works alongside encapsulation to provide a clear distinction between an object’s external interface and internal workings.


5. Real-world Example of Abstraction

Let's take an example from the real world to understand abstraction better.

Example: ATM Machine

When we use an ATM machine, we interact with the following essential features:

  • Insert your card.

  • Enter your PIN.

  • Withdraw money.

You don’t need to know the internal working of how the ATM communicates with the bank’s server, how the PIN verification happens, or how the money is dispensed from the machine. These internal processes are hidden from you, and you only interact with the high-level functionalities. This is abstraction in practice.


6. Java 8 and Abstraction (Default Methods)

In Java 8, default methods were introduced in interfaces, which allow you to add concrete methods in interfaces without breaking the existing implementations. This feature allows interfaces to be more flexible and maintainable, without enforcing subclasses to override every method.

Example of Default Method in Interface:
interface Vehicle {
    void start();  // Abstract method

    // Default method
    default void stop() {
        System.out.println("Vehicle has stopped.");
    }
}

class Car implements Vehicle {
    @Override
    public void start() {
        System.out.println("Car is starting.");
    }
}

public class Main {
    public static void main(String[] args) {
        Car car = new Car();
        car.start();  // Calls the start method from Car
        car.stop();   // Calls the default stop method from Vehicle interface
    }
}

Explanation:

  • The Vehicle interface has a default method stop() with an implementation.

  • The Car class implements the start() method but does not need to override the stop() method because it is already provided by the interface.


7. Best Practices for Using Abstraction

  • Use Abstract Classes when you want to share common code among closely related classes and allow them to define their specific behaviors.

  • Use Interfaces when you want to define a contract for unrelated classes that should follow the same behavior.

  • Use abstraction to separate concerns and organize your code logically.

  • Keep your abstract classes and interfaces focused on high-level functionality, avoiding implementation-specific details.


Summary

By the end of Day 11, readers will have a deep understanding of:

  1. What abstraction is and its importance in Java programming.

  2. How to implement abstraction using abstract classes and interfaces.

  3. The key differences between abstract classes and interfaces.

  4. Real-world examples of abstraction in practice.

  5. How Java 8's default methods enhance the abstraction provided by interfaces.

Abstraction is a powerful concept that helps simplify complex systems and makes code easier to maintain and extend. By understanding how to use abstract classes and interfaces effectively, you can build more modular, maintainable, and flexible Java applications. Stay tuned!! for further Advanced topics related to Java.

10
Subscribe to my newsletter

Read articles from Mohit Upadhyay directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Mohit  Upadhyay
Mohit Upadhyay