Java

Why use Abstract Classes in Java?

Abstract classes in Java are templates that cannot be instantiated directly and may include abstract methods (without implementation) and concrete methods (with implementation). They are used to define common behaviors that subclasses must implement while sharing reusable code. Abstract methods act as placeholders, enforcing a contract that subclasses must fulfill.

Let’s look at an example. Imagine a veterinary system; we need to have information about animals. For instance, a dog and a cat are both animals.

public abstract class Animal {
    protected String name;

    public Animal(String name) {
        this.name = name;
    }

    public abstract void makeSound();

    public void eat() {
        System.out.println(name + " is eating.");
    }
}
class Dog extends Animal {
    public Dog(String name) {
        super(name);
    }

    @Override
    public void makeSound() {
        System.out.println(name + " says: Woof!");
    }
}
class Cat extends Animal {
    public Cat(String name) {
        super(name);
    }

    @Override
    public void makeSound() {
        System.out.println(name + " says: Meow!");
    }
}

We have 3 classes: the Animal class, which is abstract and cannot be instantiated.

Why create a class that cannot be instantiated?

This depends on the business context. In this specific case, it’s important to know which animal needs attention; we can’t use something generic. We need to know if it’s a cat or a dog because this impacts the veterinary treatment. Therefore, in this case, it’s necessary to specify if it’s a cat or dog. So, we can’t instantiate an animal directly, but we can instantiate a dog or a cat, which are also animals but more specific.

Benefits:

  • Code reuse: we can leverage common attributes and methods in all subclasses;
  • Polymorphism: we can use the Animal class to enable polymorphism, as a dog is an animal, and so is a cat;
  • Extensibility: adding a new class, such as Bird, becomes straightforward;
  • Partial implementation: the makeSound method is abstract, so the subclasses are responsible for providing their own implementation.

Author

  • Natan Ferreira

    I am a seasoned Full Stack Software Developer with 8+ years of experience, including 6+ years specializing in Java with Spring and Quarkus. My core expertise lies in developing robust RESTful APIs integrated with Cosmos Db, MySQL, and cloud platforms like Azure and AWS. I have extensive experience designing and implementing microservices architectures, ensuring performance and reliability for high-traffic systems. In addition to backend development, I have experience with Angular to build user-friendly interfaces, leveraging my postgraduate degree in frontend web development to deliver seamless and responsive user experiences. My dedication to clean and secure code led me to present best practices to my company and clients, using tools like Sonar to ensure code quality and security. I am a critical thinker, problem solver, and team player, thriving in collaborative environments while tackling complex challenges. Beyond development, I share knowledge through my blog, NatanCode, where I write about Java, Spring, Quarkus, databases, and frontend development. My passion for learning and delivering innovative solutions drives me to excel in every project I undertake.