! Critical Distinction — Abstract Class ≠ Abstraction
Today we study abstract classes — a Java keyword and mechanism.
This is NOT the same as the
2nd pillar of OOP called "Abstraction".
Many students confuse these two. Let us be absolutely clear:
- An OOP design principle
- Hiding internal details from users
- Showing only what is necessary
- Example: you drive a car without knowing its engine internals
- Achieved by interfaces, encapsulation, abstract classes
- A Java language feature (
abstractkeyword) - A class that cannot be instantiated
- May contain abstract methods (no body)
- Must be subclassed to be used
- Today's topic!
Abstraction is the concept (what we want to achieve). Abstract class is one tool in Java that helps us achieve it — but they are not the same thing.
1 What Does "Abstract" Mean?
Before we write a single line of code, we must understand the word itself. Programming is built on real-world thinking, so let us start with the English meaning.
Not tied to one specific thing
"Shape" — you picture something,
but which shape exactly?
"Animal" — exists, but which one?
"Vehicle" — but what kind?
Represents one definite thing
"Circle" — no doubt, you know it!
"Cat" — specific, exists in reality
"Car" — clear, identifiable object
🦌 Animal Hierarchy:
In the real world, the definition of an object (from OOP) is: an entity that represents a specific, identifiable thing in the real world. An abstract concept does not satisfy this definition — you cannot point at a "shape" sitting on a table. You can only point at a circle, a rectangle, or a triangle.
2 Class Discussion — Discovering Abstract Classes
Story 1 🖌 The Professor and the Shape
🏫 In the classroom...
The student pauses...
Yes, a circle IS a shape — absolutely correct! But I said "shape", not "circle". So which shape did I mean? A square? A triangle? You cannot know, because "shape" does not specify a particular object!
Conclusion: "Shape" does not represent a specific object. It is an abstract concept.
Story 2 🏪 The Farm and the Animal
🏫 On a farm with sheep, goat, dog, cat...
This is the key: "animal" does not represent a specific object in reality. It is an abstract idea. The concrete things are: goat, sheep — each is specific and identifiable.
"Animal" fails this test → abstract.
"Goat" passes it → concrete.
"Shape" fails this test → abstract.
"Circle" passes it → concrete.
Therefore: it is not logical to create an object of "Animal" or "Shape".
3 "Then Why Have Shape at All?"
If we agree we cannot create an object of Shape — a smart student will raise their hand:
Shape, then
why do we have it at all? Why not just define Circle, Rectangle,
and Triangle directly?
Circle, Rectangle, and Triangle all share common
attributes (e.g., color) and common behaviors (e.g., getColor()).
Without Shape, we would repeat this code in every subclass.
Inheritance eliminates redundancy.
To treat Circle, Rectangle, and Triangle
polymorphically (one array, one loop, one method),
they must be related by an IS-A relationship.
Shape provides that common ancestor.
No Shape = no polymorphism between them.
We keep Shape because we need it for
inheritance (shared attributes/methods) and
polymorphism (IS-A relationship) —
even though we never create a Shape object directly.
4 The abstract Class — Syntax & Meaning
We agree: it is not logical to create an object of Shape.
But programmatically, Java does not automatically prevent it — unless we tell it to.
The solution: declare the class as abstract.
// ERROR! Shape is abstract
// OK! Circle IS-A Shape
- Incomplete — has at least one method without a body
- Cannot be instantiated (
new Shape()= error) - Must be subclassed
- Represents a concept too general to be a real object
- Complete / fully built — all methods have implementations
- Can be instantiated (
new Circle()= OK) - Represents a specific, real-world object
- A class with no
abstractkeyword is concrete
An abstract class is a class declared with the abstract keyword.
It is incomplete — it cannot be instantiated directly.
But it can have concrete attributes (like color)
and concrete methods (like getColor()) —
the "incomplete" part refers only to the abstract methods that have no body yet.
Those attributes and concrete methods are fully inherited by every subclass.
5 Abstract Methods — Incomplete by Design
The Problem Can getArea() have a generic implementation?
Shape has a method called getArea().
My students — can anyone give me a single formula for the area that works for ALL shapes?- Circle: π × r²
- Rectangle: width × height
- Triangle: Heron's formula
getArea() from Shape
and put it only in each subclass." But wait — what problem does this create?getArea() is not in Shape, then when we treat
shapes polymorphically, we cannot call s.getArea() on a Shape reference —
the compiler will reject it! Polymorphism works through the reference type (Shape),
so the method must be declared there.Pentagon extends Shape and forgets to implement getArea()?
If getArea() is in Shape with a body (e.g., return 0;),
Pentagon silently inherits the wrong implementation and there is no warning!The solution: declare getArea() as ABSTRACT in Shape.
Syntax Abstract Method Declaration
- Only the signature/header is declared
- No body — no
{ } - Ends with a semicolon
; - Forces subclasses to provide the implementation
- Guarantees the behavior EXISTS in all subclasses
- Guarantee 1: Every concrete subclass WILL have
getArea() - Guarantee 2: It WILL have a real implementation (not a default
return 0) - The compiler enforces both — no developer can forget!
Example Complete Shape Hierarchy
6 The Rules of Abstract Classes
Study each rule carefully. Each one has an example to make it concrete.
If a subclass provides a @Override implementation for
every abstract method it inherited, the compiler considers it complete
— it becomes a normal (concrete) class and you can create objects of it.
If a subclass implements some but not all abstract methods, it is still
incomplete. The compiler forces it to also be declared abstract.
You cannot have an abstract method inside a non-abstract class. The class becomes incomplete the moment it contains an abstract method, so it must be abstract too.
Even if the developer does not plan to use a particular method — they must still implement it. The compiler enforces this with no exceptions. This is exactly what we want!
You can declare a class abstract even if it has no abstract methods at all.
This simply prevents instantiation — useful when the class is logically incomplete,
even though all its methods have implementations.
Sometimes the concept is not logical to instantiate (like Animal or Vehicle),
even if all behaviors have reasonable default implementations. Making it abstract
expresses this design intent clearly.
Abstractness does not flow only top-down. A subclass of a concrete class can itself
be abstract. A famous real-world example: the Object class
in Java is concrete — yet Shape (which extends Object) can be abstract.
Even though you cannot create a new Shape(), you CAN declare a
variable, an array, or a method parameter
of type Shape. This is the foundation of polymorphism!
This is a powerful and often surprising rule. A subclass can take a method that was fully implemented in its parent, and re-declare it as abstract — forcing its own subclasses to provide a new implementation. This is the basis of the Manager Technique we will see next.
7 The Manager Technique — Forcing toString()
This is a real-world application of Rule 8 that every software manager should know.
💼 Real Scenario at a Software Company
toString() method.
This is our company standard — no exceptions!- The compiler becomes the manager's assistant — no reminders needed
- A developer cannot compile their class without providing a proper
toString() - This technique combines Rule 6 (abstract subclass of concrete superclass) and Rule 8 (making a concrete method abstract)
- Used in real Java frameworks and large enterprise codebases
8 Case Study — java.lang.Number (Abstract in the Real Java API)
Everything we studied today exists right inside Java's standard library.
The perfect example: java.lang.Number.
Number is the abstract superclass of all numeric
wrapper classes in Java. It is declared as:
public abstract class Number extends Object
It has abstract methods that every numeric subclass must implement.
You cannot do new Number() — it is abstract!
Polymorphism Using Number as a Data Type
Java's own designers used the abstract class pattern for Number
for exactly the same reasons we use it for Shape:
"Number" is too general to have its own object, but it provides a shared interface
and IS-A relationship for all numeric types — enabling polymorphism across the entire numeric hierarchy.
★ Summary — What You Learned Today
An abstract class is a class that is declared with the
abstract keyword.
It may contain abstract methods (header only, no body)
and/or concrete methods. It cannot be instantiated,
but it can be used as a data type for polymorphism.
Any class that inherits abstract methods must either
implement all of them (becoming concrete)
or declare itself abstract too.