Abstraction & abstract classes
Abstract methods and classes, template methods and when abstraction helps.
Abstraction means showing what something does while hiding how it does it. When you call list.sort() or drive a car, you use a simple interface and ignore the machinery underneath. In class design, abstraction means capturing the common idea ("every shape has an area") without pretending to know details that only specific subclasses can provide.
In the polymorphism lesson our base Shape had double area() { return 0; }. That is a lie: there is no sensible area for a generic shape, and nothing stops someone writing new Shape() or forgetting to override area(). Abstract classes fix both problems.
Abstract methods and abstract classes#
An abstract method has a signature but no body. It says "every subclass must provide this". A class with at least one abstract method must itself be declared abstract, and an abstract class cannot be instantiated.
What the compiler now guarantees:
- Nobody can create a meaningless plain
Shape. - Every concrete subclass must implement
area()andperimeter(), or it will not compile:
Even though you can't write new Shape(...), the abstract class still has a constructor. It runs as part of building every subclass object, through super(name). Making it protected documents that only subclasses should call it.
The rules in one place#
abstractmethods have no body (just a;) and cannot beprivate,staticorfinal(all of those prevent overriding).- A class with any abstract method must be
abstract. A class can also beabstractwith no abstract methods, purely to prevent instantiation. - An abstract class can have fields, constructors, static members, and concrete methods of any visibility.
- A subclass either implements all inherited abstract methods or is declared
abstractitself. abstractandfinalcan never be combined on a class: one demands subclasses, the other forbids them.- You can use the abstract type for variables, parameters, arrays and return types:
Shape s = new Circle(...).
A partially abstract hierarchy#
Abstract classes can stack. A middle layer can implement some methods and leave the rest for its children:
The template method pattern#
A very common use of abstract classes is the template method: the parent defines the steps of an algorithm in a final method and lets subclasses fill in individual steps. The overall flow is fixed in one place; only the variable parts change.
You will meet this pattern all over the JDK and frameworks: java.io.InputStream is abstract, with read() abstract and many concrete methods built on top of it; AbstractList gives you a full List if you implement just get() and size().
Anonymous subclasses#
For a one-off implementation you can subclass an abstract class inline, without naming the class:
new Greeter() { ... } doesn't create a Greeter; it creates an object of a nameless subclass. For interfaces with a single method, a lambda (covered later) is usually neater.
When does abstraction help?#
Use an abstract class when:
- Several related classes share state and code, and the shared base makes no sense on its own (
Shape,Employee,Report). - You want to fix the skeleton of an algorithm and let subclasses vary the steps (template method).
- You want to provide a partial implementation of a bigger contract to save subclasses work.
If you only need a contract (a set of method signatures) with no shared state, or a class needs to fit several roles at once, an interface is usually the better choice. That is the next lesson, and it ends with a side-by-side comparison.
Don't add abstraction speculatively. One concrete class is easier to read than an abstract base with one subclass. Extract an abstract class when you have (or clearly will have) two or more real variants.
Common mistakes#
- Trying to instantiate an abstract class with
new. - Giving an abstract method a body, or forgetting the
abstractkeyword on a method without one (missing method body, or declare abstract). - Making an abstract method
private,staticorfinal. - Forgetting to implement one abstract method in a concrete subclass.
- Calling overridable abstract methods from the abstract class's constructor: the subclass fields aren't initialised yet when the parent constructor runs.
What's next#
Abstract classes still tie you to single inheritance. Interfaces let a class sign up for many contracts at once, and since Java 8 they can even carry default method implementations.
Check your understanding
Quick quiz
1.What happens if you write
new Shape()whereShapeis declaredabstract?2.A concrete (non-abstract) class extends an abstract class but does not implement one of its abstract methods. What happens?
3.Which statement about abstract classes is TRUE?
Finished reading?
Mark this lesson complete to track your progress.