Java Unveiled: The Secrets of Abstract Classes and Methods

Akash DasAkash Das
7 min read

When we talk about Java, the concepts of the abstract keyword (abstract classes and methods) is fundamental, particularly when it comes to code reusability and flexible design.

In our daily lives, many tools we use from simple appliances like TVs, fans, and refrigerators to essential devices like mobile phones and laptops are designed with abstraction in mind. These devices hide their internal workings and complexities from us while providing the functionalities we need. For example, when you press a button on a remote control, you don’t need to know how the TV processes that signal; you just want it to work.

This principle of hiding complexity and exposing only what is necessary is central to abstraction in programming. In Java, abstraction allows us to define a common interface or abstract class that outlines the expected behavior of various objects without detailing how these behaviors are implemented.

Key Concepts of Abstraction :

  1. Abstract Classes :

    An abstract class in Java is basically a class that you can’t create an instance of on its own. It can have both abstract methods which are methods without any implementation and concrete methods, which are the regular methods that do have an implementation. The main purpose of an abstract class is to serve as a foundation for other classes to build upon. It allows those subclasses to inherit common features, giving them a shared interface while still allowing for flexibility in how they implement specific behaviors. This way, you get a nice balance of structure and adaptability in your code.

    Let's understand it through a short story. I hope you guys like stories, so let's dive in.

    The Story of the Magical Library: Understanding Abstract Classes

    In a magical land, there existed a grand library known as the Library of Stories. This library had a unique way of organizing its books. Instead of just stacking them on shelves, it used a system based on the type of stories they told.

    The Blueprint: Story

    At the center of the library’s organization was an ancient scroll called Story. This scroll was special; it couldn't be checked out or read on its own. Instead, it served as a blueprint for all kinds of stories that could be found in the library.

    The scroll defined two important things:

    1. An Abstract Method: tellStory()

      • This was a magical incantation that every story had to perform, but the way each story told its tale was unique.
    2. A Concrete Method: showGenre()

      • This method simply explained the genre of the story, like “Fantasy,” “Mystery,” or “Adventure.”

Here’s what the Story scroll looked like:

// Abstract class
abstract class Story {
    // Abstract method
    abstract void tellStory(); // No implementation, just a promise to tell a story

    // Concrete method
    void showGenre() {
        System.out.println("This is a story.");
    }
}

The Unique Stories: Fairy Tale and Mystery

From the Story scroll came many unique tales. Two of the most popular were Fairy Tale and Mystery.

  1. Fairy Tale:

    • This story had magical creatures and enchanted forests. When you checked out a Fairy Tale, it would charm you with its whimsical narrative.

        // Subclass for Fairy Tale
        class FairyTale extends Story {
            @Override
            void tellStory() {
                System.out.println("Once upon a time in a magical land, there lived a kind princess and a brave knight...");
            }
        }
      
  2. Mystery:

    • This story was full of suspense and unexpected twists. When you checked out a Mystery, it would keep you guessing until the very end.

    •   // Subclass for Mystery
        class Mystery extends Story {
            @Override
            void tellStory() {
                System.out.println("In the dimly lit room, the detective discovered a clue that would change everything...");
            }
        }
      

      The Grand Reading Event

      One day, the library decided to host a grand reading event. All the townsfolk were invited, and they were eager to hear stories from their favorite genres.

      The librarian, with a twinkle in her eye, chose stories from both Fairy Tale and Mystery to showcase. Here’s how the event unfolded:

public class Main {
    public static void main(String[] args) {
        Story myFairyTale = new FairyTale();
        Story myMystery = new Mystery();

        myFairyTale.showGenre(); // Output: This is a story.
        myFairyTale.tellStory();  // Output: Once upon a time in a magical land...

        myMystery.showGenre(); // Output: This is a story.
        myMystery.tellStory();  // Output: In the dimly lit room, the detective...
    }
}

The Takeaway

As the townsfolk listened to the enchanting stories, they realized that even though both stories came from the same Story scroll, each had its unique way of telling its tale. The Story scroll provided a common structure, ensuring that all stories had a genre to display and a promise to tell a story, but the specifics were left to each individual story.

The Lesson of the Library

In this magical library, the concept of an abstract class was beautifully illustrated. The Story scroll acted as a blueprint, allowing different stories to inherit common features while maintaining their unique identities. This made the library not just a place of books, but a realm of endless imagination, where every story could shine in its own way! Each tale, with its unique voice and style, showcased the beauty of diversity within a shared framework.

Advantages of Abstract Classes

  1. Common Structure: Provides a clear template for subclasses, ensuring they share common methods and attributes.

  2. Code Reusability: Allows shared code and functionality in the abstract class, reducing redundancy in subclasses.

  3. Enforced Implementation: Requires subclasses to implement abstract methods, promoting consistency across related classes.

  4. Supports Multiple Concrete Methods: Can contain both abstract and concrete methods, offering flexibility in design.

  5. Facilitates Polymorphism: Allows treating different subclasses as instances of the abstract class, enabling polymorphic behavior.

Disadvantages of Abstract Classes

  1. Cannot be Instantiated: Abstract classes cannot be created directly, limiting their use as standalone objects.

  2. Single Inheritance: Java only allows a class to inherit from one abstract class, restricting flexibility in certain designs.

  3. Tight Coupling: Subclasses are tightly coupled to the abstract class, which can make changes more complex and affect all derived classes.

  4. Potential for Unused Methods: If not all methods are relevant for all subclasses, it can lead to unused or irrelevant methods in some subclasses.

  5. Less Flexibility Compared to Interfaces: Abstract classes can limit design flexibility compared to interfaces, which allow multiple inheritances.

Abstract Methods :

Did you notice the abstract method in the above example? In the scenario, the Story class contains an abstract method called tellStory().

Let's understand what an abstract method is :

An abstract method is a method that is declared without an implementation.

It means that the method does not have a body and must be implemented by subclasses. This allows different subclasses to provide their own specific implementation of the method, ensuring flexibility and reusability in the code.

Why abstract methods ?

  1. Common Structure: Provides a clear blueprint for subclasses, ensuring they all have the required method.

  2. Enforced Implementation: Requires subclasses to implement the method, promoting consistency.

  3. Code Reusability: Reduces code duplication by allowing shared methods in the abstract class.

  4. Polymorphism: Enables treating different subclasses as a common type, simplifying code and enhancing flexibility.

  5. Encourages Creativity: Allows each subclass to implement the method in its own unique way, fostering diverse functionalities.

In conclusion, abstract classes and methods in Java provide a powerful way to achieve code reusability and flexible design. By defining a common structure and enforcing implementation through abstract methods, we can create a robust and adaptable codebase. The story of the magical library beautifully illustrates how abstract classes serve as blueprints, allowing subclasses to inherit common features while maintaining their unique identities. This balance of structure and flexibility is key to writing efficient and maintainable code.

I hope this article has helped you understand the importance and application of abstract classes and methods in Java. Your feedback is valuable to me, so please share your thoughts and suggestions. How did you find the explanations and examples? Is there anything more you would like to see or any areas that need further clarification? Let me know!

Happy Coding !!!

0
Subscribe to my newsletter

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

Written by

Akash Das
Akash Das

Java Developer | Tech Blogger | Spring Boot Enthusiast | DSA Advocate*I specialize in Java, Spring Boot, and Data Structures & Algorithms (DSA). Follow my blog for in-depth tutorials, best practices, and insights on Java development, Spring Boot, and DSA. Join me as I explore the latest trends and share valuable knowledge to help developers grow.