Abstract Classes in Java
Soresa
Last Update 3 years ago
There are many cases when implementing a contract where we want to postpone some parts of the implementation to be completed later. We can easily accomplish this in Java through abstract classes.
In this tutorial, we'll learn the basics of abstract classes in Java, and in what cases they can be helpful.
Key Concepts for Abstract Classes
Before diving into when to use an abstract class, let's look at their most relevant characteristics:
- We define an abstract class with the abstract modifier preceding the class keyword
- An abstract class can be subclassed, but it can't be instantiated
- If a class defines one or more abstract methods, then the class itself must be declared abstract
- An abstract class can declare both abstract and concrete methods
- A subclass derived from an abstract class must either implement all the base class's abstract methods or be abstract itself
To better understand these concepts, we'll create a simple example.
Then, we can create a subclass that implements the play method:
When to Use Abstract Classes
Now, let's analyze a few typical scenarios where we should prefer abstract classes over interfaces and concrete classes:
- We want to encapsulate some common functionality in one place (code reuse) that multiple, related subclasses will share
- We need to partially define an API that our subclasses can easily extend and refine
- The subclasses need to inherit one or more common methods or fields with protected access modifiers
Note that code reuse is a very compelling reason to use abstract classes, as long as the “is-a” relationship within the class hierarchy is preserved.
A Sample Hierarchy of File Readers
To understand more clearly the functionality that abstract classes bring to the table, let's look at another example.
Defining a Base Abstract Class
So, if we wanted to have several types of file readers, we might create an abstract class that encapsulates what's common to file reading:
Note that we've made filePath protected so that the subclasses can access it if needed. More importantly, we've left something undone: how to actually parse a line of text from the file's contents.
Our plan is simple: while our concrete classes don't each have a special way to store the file path or walk through the file, they will each have a special way to transform each line.
At first sight, BaseFileReader may seem unnecessary. However, it's the foundation of a clean, easily extendable design. From it, we can easily implement different versions of a file reader that can focus on their unique business logic.
Defining Subclasses
Or another might be one that converts a file's contents to uppercase:
As we can see from this simple example, each subclass can focus on its unique behavior without needing to specify other aspects of file reading.
Using a Subclass
Finally, using a class that inherits from an abstract one is no different than any other concrete class:
Conclusion
In this quick article, we learned the basics of abstract classes in Java, and when to use them for achieving abstraction and encapsulating common implementation in one single place.
