Introduction
In our last lesson, we explored how Java interfaces act as pure contracts, defining what a class can do without specifying how. You might have wondered if there's a way to create a contract that also provides some default behavior or shared state. That is precisely where abstract classes come in.
This lesson focuses on creating and extending abstract classes. We'll build on your understanding of interfaces to see how abstract classes offer a powerful middle ground between a fully abstract contract (an interface) and a fully concrete implementation (a regular class). Our primary goal is to clearly distinguish the purpose of an abstract class from that of an interface, so you can confidently choose the right tool for the right job—a crucial skill for designing robust software and understanding design patterns.
What is an Abstract Class?
An abstract class is a special type of class that cannot be instantiated on its own. It's designed to be a base, or a blueprint, from which other classes can inherit. The key feature of an abstract class is that it can contain a mix of both regular, implemented methods and abstract methods—methods that are declared without an implementation, just like in an interface.
A subclass that extends an abstract class inherits all of its implemented methods and fields, but it is forced to provide an implementation for any abstract methods.
This video from the "Coding with John" channel provides a fantastic introduction.
Abstract Classes and Methods in Java Explained in 7 Minutes
This tutorial clearly explains the core concepts of an abstract class: non-instantiability, abstract methods, and the ability to include concrete methods.
Please watch the following three segments: First, watch the introduction from the beginning, which uses an Animal example to explain why you would want a class that cannot be directly instantiated. Next, watch the segment on abstract methods, which demonstrates how an abstract makeNoise() method forces subclasses like Cat to provide their own implementation. Finally, see how abstract classes can also contain concrete methods that are simply inherited.
To formalize this, let's turn to the official Java documentation.
Abstract Methods and Classes (The Java™ Tutorials ...
This document from Oracle provides the definitive explanation and a classic example.
First, read the introductory section, Abstract Methods and Classes, for the formal definition. Then, jump down to the section An Abstract Class Example. The GraphicObject example here is a perfect illustration. Notice how the abstract class can manage shared state (like position) and provide a concrete moveTo() method, while leaving the draw() and resize() methods for concrete subclasses like Circle and Rectangle to implement.
Here's the code from that GraphicObject example, which brings the concepts together:
// Abstract blueprint for all graphic objects
abstract class GraphicObject {
int x, y; // Shared state
// A concrete method, shared by all subclasses
void moveTo(int newX, int newY) {
this.x = newX;
this.y = newY;
System.out.println("Moved to x:" + x + " and y:" + y);
}
// Abstract methods - a contract for subclasses
// Notice they have no body, just a semicolon.
abstract void draw();
abstract void resize();
}
class Circle extends GraphicObject {
@Override
void draw() {
System.out.println("Drawing a Circle at " + x + ", " + y);
}
@Override
void resize() {
System.out.println("Resizing the Circle");
}
}
class Rectangle extends GraphicObject {
@Override
void draw() {
System.out.println("Drawing a Rectangle at " + x + ", " + y);
}
@Override
void resize() {
System.out.println("Resizing the Rectangle");
}
}
Abstract Class vs. Interface: Making the Choice
Now we arrive at the central question: when do you use an abstract class, and when do you use an interface? While they seem similar, they serve different design purposes.

Let's break down the technical differences, which guide the design choice.
| Feature | Abstract Class | Interface |
|---|---|---|
| Inheritance | A class can extend only one abstract class. |
A class can implements multiple interfaces. |
| Methods | Can contain a mix of abstract and non-abstract methods. |
All methods are implicitly public abstract (before Java 8). |
| Fields (Variables) | Can have instance variables (state) with any visibility. | Can only have public static final constants. |
| Constructors | Can have constructors (called by subclass constructors). | Cannot have constructors. |
| Purpose | To provide a common base with shared code for related classes. | To define a contract of capabilities for potentially unrelated classes. |
The "Coding with John" video you watched earlier has an excellent segment that directly compares these two concepts.
Abstract Classes and Methods in Java Explained in 7 Minutes
This segment summarizes the most important distinctions you'll need to remember.
Please watch the part of the video that discusses the differences. Pay close attention to the points about single vs. multiple inheritance and the crucial difference in how fields (instance variables) are handled.
A Practical Heuristic: "Is-A" vs. "Can-Do"
With the technical differences in mind, we can establish a simple but powerful rule of thumb for making a decision:
-
Use an Abstract Class for an "is-a" relationship.
Choose an abstract class when you can say "A is a B." For example, aDogis anAnimal. ACaris aVehicle. This model works best when you have a group of closely related classes that share common fields and methods. The abstract class provides a skeletal implementation that the subclasses can build upon. -
Use an Interface for a "can-do" relationship.
Choose an interface when you want to specify a capability that various, otherwise unrelated, classes can possess. For example, aBirdcanFly, but so can aPlane. ACarcan beSerializable, but so can aUserSessionobject. The interface defines a contract for what it means to be "flyable" or "serializable."
The following resource from Baeldung articulates this heuristic very well.
Using an Interface vs. Abstract Class in Java
This article provides clear guidelines and code examples for when to use each construct.
First, read the brief comparison in Section 3, "Interface vs. Abstract Class". Then, read Section 5, "When to Use an Abstract Class". The "A is a B" rule and the Vehicle example perfectly capture the primary use case for an abstract class.
Let's see this "is-a" concept with one final, memorable example from "The Code Hard Truth" channel, which uses a wrestling analogy.
Abstract Classes vs Interfaces (Java)
This video does an excellent job of showing an abstract class providing both generalized, concrete behavior and unique, abstract behavior that subclasses must define.
Watch the section explaining the Wrestler abstract class example. Notice how all wrestlers share the same payment logic (a concrete method), but each wrestler subclass (Kane, Stone Cold) is forced to provide its own unique themeMusic and finisher (the abstract methods). This is a perfect demonstration of the "is-a" relationship with shared code.
Conclusion
In this lesson, we demystified abstract classes and established their role alongside interfaces in object-oriented design. You now have two powerful tools for creating abstractions in Java.
Here are the essential takeaways:
- An abstract class is a blueprint that cannot be instantiated. It is defined with the
abstractkeyword. - It serves as a base for subclasses, providing a combination of shared state (fields), shared behavior (concrete methods), and a contract (abstract methods).
- A Java class can only
extendone abstract class, making it suitable for strong "is-a" relationships. - The decision framework is key:
- Choose an abstract class when you want to share code among closely related classes (
Caris aVehicle). - Choose an interface when you want unrelated classes to share a common capability (
BirdcanFly,PlanecanFly).
- Choose an abstract class when you want to share code among closely related classes (
In our next lesson, we will tie all of this together by exploring polymorphism. You'll see how you can write code that operates on an abstract type—like a GraphicObject or a Predator—without needing to know the specific concrete class (Circle, Rectangle, Fish, Hawk). This principle is the foundation for almost every design pattern you will learn.