Abstract Class in Java

by Dimitris Tasios
479 views

In this article, we will see what an abstract class in Java is and how to use one.

1. What Is an Abstract Class in Java?

In Java, an abstract class is a class that is used as a prototype for other classes. Because of their special purpose, they do have some characteristics that differentiate them from non-abstract classes. Let’s see the main characteristics of an abstract class in Java:

  1. We cannot instatiate an abstract class, because it’s a blueprint for other classes. As a result, we cannot create an object of an abstract class, using the new keyword.
  2. In order to define a class as abstract, we use the abstract keyword.
  3. An abstract class can have methods that are either also abstract or non-abstract (more on abstract methods in the following subsection).
  4. Despite not being able to create an object from an abstract class, we can have constrcuctors.
  5. They cannot be final because the purpose of an abstract class is to be extended by a child class.
  6. Finally, they can have static methods ,as well as non-static fields. This rule also aplies for class fields, as they can be either static or non-static, just like in non-abstract classes (remember that, on the other hand, the fields of interfaces are always public static final).

2. Abstract Methods

Similar to classes, there are also abstract methods, which are methods without implementation (so they don’t have a body). The following characteristics are true for abstract methods:

  1. Abstract methods are also delcared with the abstract keyword, just like abstract classes.
  2. Instead of a body, we use a semicolon (;) at the end of its signature, instead of an opening curly brace ({).
  3. An abstract method can only exist in an abstract class. If the class is not abstract, no method can be abstract. On the other side, as previously noted, an abstract have may have abstract methods, but it may also not.
  4. Abstract methods cannot be final because a child class must provide an implementation for it.
  5. Additionally, an abstract method cannot be private because it would be inaccessible to other classes.

3. An Example of an Abstract Class

Let’s see those characteristics in action. We have created an abstract class, Animal which has the following fields and methods:

  • private static int animalsBorn: a counter that shows how many animals there are. Notice that because it’s static, all classes that extend the Animal class share the same counter.
  • Animal(): the constructor of the abstract class. This will be automatically called whenever a child class is created. Inside the constructor we print a message indicating the creation of an animal and, also, increase the animalsBorn by one. The reason we define a constructor for an abstract class (that cannot create object on its own) is to, perhaps, initialize some fields whenever it’s called by a child class.
  • abstract void talk(): an abstract method that each child class can implement differently, since we can’t know the sound of an animal without knowing what kind of animal it is first.
  • public void run(): a regular method that is available to all children classes. It prints a message that describes that the animal is running.
  • public static final int getTotalAnimalsBornNumber(): a static getter of the animalsBorn counter. Notice that because it’s final no other subclass can override it with its own implementation, which is something we want in this scenario.
abstract class Animal {

    // The total number of animals that exist across all usages of Animal abstract class
    private static int animalsBorn = 0;

    // Whenever a new child class is created, the counter of Animal increases by one
    Animal() {
        System.out.println("A new animal is born.");
        animalsBorn++;
    }

    // the sound an animal can make that's different between animals
    abstract void talk();

    // regular method, common to all animals
    public void run() {
        System.out.println("Running like the wind!");
    }

    // getter for animalsBorn, unrelated to a specific animal (belongs to the class not the object, therefore static)
    public static final int getTotalAnimalsBornNumber() {
        return animalsBorn;
    }
}

4. An Example of a Class That Extends an Abstract Class

Moving on with our previous example, we can now define two animals, as such:

class Dog extends Animal {
    @Override
    void talk() {
        System.out.println("The dog goes woof-woof!");
    }
}

class Cat extends Animal {
    @Override
    void talk() {
        System.out.println("The cat goes meowww!");
    }
}

We have created a Dog and a Cat class that each extends the Animal abstract class. Then, each class implements talk() in its own way. For a Dog this method makes the animal bark, and for a Cat it makes it meow.

Since both of these classes are extending Animal they must implement the talk() method. If we didn’t want to implement that method, we could do either of the two:

  1. Override the method but provide an empty body to it, effectively doing nothing.
  2. Or, declare the child class abstract as well.

5. Putting Everything Together

Finally, let’s see how we can use all those classes together:

class JavaAbstractClassAndMethodsExampleClass {
    public static void main(String[] args) {

        Animal animal = new Dog(); // same as Dog newDog = new Dog();
        animal.talk();
        animal.run();

        System.out.println();

        animal = new Cat(); // same as Cat newCat = new Cat();
        animal.talk();
        animal.run();

        System.out.println("\nTotal animals: " + Animal.getTotalAnimalsBornNumber());
    }
}

The output is:

A new animal is born.
The dog goes woof-woof!
Running like the wind!

A new animal is born.
The cat goes meowww!
Running like the wind!

Total animals: 2

Let’s see what happened:

  • Line 4: We create a new Dog object. The Animal animal means that we can create either a Dog or a Cat object. Whatever is after the equals sign (=) indicates the implementation (and, thus, the methods) that will be used when we run the program. In this case, an Animal has access to the methods of Dog. In this line, the constructor Animal() is also called.
  • Lines 5-6: Because the animal is a Dog, the talk() will make the animal bark. The run() is independent of what the animal is.
  • Line 10: The animal is now a Cat, so it has access to the cat’s methods. The constructor Animal() is called again.
  • Lines 11-12: Now talk() makes the animal meow, while run() is the same as when the animal was a Dog.
  • Line 14: Whenever the constructor Animal() was called, the counter was increased by one. So, since we have created 2 animals, the counter reflects that.

6. Conclusion

By now, you should be able to create an abstract class in Java and use it effectively. You can find the source code on our GitHub page.

7. Sources

[1]: Abstract Methods and Classes, Oracle

Related Posts