Java Notes
Learn abstract classes in Java — abstract keyword, abstract vs concrete methods, when a child must override, why you cannot create abstract class objects, and when to choose abstract class over interface.
An abstract class sits between a regular class and an interface. It can have some methods fully written (with a body) and some methods declared but not written (abstract — no body). Child classes must complete the unfinished methods.
Use an abstract class when multiple related classes share some code but differ in parts of their behaviour.
The abstract Keyword
public abstract class Vehicle {
String brand;
int speed;
// Concrete method — all vehicles start the same way
void start() {
System.out.println(brand + " starting...");
}
// Abstract method — how a vehicle moves differs per type
abstract void move();
}Line by line:
abstract class Vehicle— declaring the class abstract. You cannot writenew Vehicle().void start()— has a body. Every child inherits this as-is.abstract void move();— no body, no{}. A declaration only. Every non-abstract child must provide a body.
Creating a Child Class
Try it in WoHoCode
Edit the program, then run it here.
Run this example to see its output.
Line by line:
Car extends Vehicle— Car must overridemove(). If it does not, Car must also be declared abstract.Vehicle v1 = new Car("Toyota");— upcasting. Reference isVehicle, object isCar.v1.move()— Java calls Car's version at runtime.
What Can an Abstract Class Have?
public abstract class Shape {
String color; // field — normal
public Shape(String color) { // constructor — allowed
this.color = color;
}
abstract double area(); // abstract method — no body
void printColor() { // concrete method — has body
System.out.println("Color: " + color);
}
static void info() { // static method — allowed
System.out.println("Shape is a 2D figure.");
}
}An abstract class can have:
- Fields (instance variables)
- Constructors
- Abstract methods (no body)
- Concrete methods (with body)
- Static methods
- Final methods
What it cannot do: be instantiated directly.
Abstract Class Constructor
Abstract classes can have constructors. They run when a child object is created.
Try it in WoHoCode
Edit the program, then run it here.
Run this example to see its output.
Order: Animal's constructor runs first (via super(name)), then Dog's constructor. You cannot skip the abstract class constructor.
Partial Implementation — the Real Power
Abstract classes shine when some behaviour is shared but parts differ. The shared code is written once; the differing part is forced on each subclass.
Try it in WoHoCode
Edit the program, then run it here.
Run this example to see its output.
generateReport() is final — it cannot be overridden. It defines the steps. Each subclass fills in the specific steps. This is the Template Method design pattern — and it is built on abstract classes.
Abstract Class vs Interface
| Feature | Abstract Class | Interface |
|---|---|---|
| Can have fields | Yes | Only public static final constants |
| Constructor | Yes | No |
| Concrete methods | Yes | Only as default methods (Java 8+) |
| Abstract methods | Yes | Yes (all methods are abstract by default) |
| Multiple inheritance | No (single extends only) | Yes (a class can implement many interfaces) |
| When to use | Shared code + shared state among related classes | Contract for unrelated classes |
Choose abstract class when:
- Classes share fields and some implemented methods
- The classes are genuinely related (all are types of Vehicle, Animal, etc.)
Choose interface when:
- You need a contract that unrelated classes can fulfill
- You need multiple inheritance of type
- You want to define a capability (Printable, Serializable, Comparable)
Common Mistake 1: Trying to Instantiate an Abstract Class
Shape s = new Shape("red"); // COMPILE ERROR
Shape s = new Circle("red", 5.0); // CORRECTAn abstract class is incomplete — some methods have no body. Java prevents you from creating one.
Common Mistake 2: Forgetting to Override All Abstract Methods
public abstract class Animal {
abstract void eat();
abstract void sleep();
}
// COMPILE ERROR — sleep() is not overridden
public class Dog extends Animal {
@Override
void eat() { System.out.println("Dog eats"); }
// sleep() missing
}
// Must override all, OR declare Dog also abstract
public abstract class Dog extends Animal {
@Override
void eat() { System.out.println("Dog eats"); }
// sleep() can be left to Dog's subclasses
}Practice Task
Task: Create an abstract class Employee with fields name and baseSalary, a concrete method printName() that prints the employee name, and an abstract method calculateBonus() returning double. Create two subclasses: SalesEmployee (bonus = 20% of baseSalary) and SupportEmployee (fixed bonus of Rs.5000). In main, store both in an Employee[] and print name + bonus for each.
Hint: Call super(name, baseSalary) from each subclass constructor. The loop can call e.printName() and e.calculateBonus().
Solution:
Try it in WoHoCode
Edit the program, then run it here.
Run this example to see its output.
What to observe: calculateBonus() works differently for each type. The loop does not check which type — it just calls the method. Adding a new employee type (e.g., HREmployee with a 10% bonus) requires only a new class; the loop needs no changes.
Continue the lesson path