Abstract Classes and Abstract Methods
Every employee gets a payslip with the same layout: name, employee id, pay for the month. Only the pay calculation differs: full-time staff get a fixed salary, contractors are paid by the hour. An abstract class lets you write the shared part once (the payslip layout) and leave a blank (the pay calculation) that every subclass must fill in. You can't create an object of the abstract class itself, because it isn't finished.
A Class with a Blank
public class Payslips {
abstract static class Employee {
private final String name;
private final String id;
Employee(String name, String id) {
this.name = name;
this.id = id;
}
abstract long monthlyPay();
String payslip() {
return id + " " + name + ": Rs. " + monthlyPay();
}
}
static class FullTimeEmployee extends Employee {
private final long salary;
FullTimeEmployee(String name, String id, long salary) {
super(name, id);
this.salary = salary;
}
@Override
long monthlyPay() { return salary; }
}
static class Contractor extends Employee {
private final int hours;
private final long ratePerHour;
Contractor(String name, String id, int hours, long ratePerHour) {
super(name, id);
this.hours = hours;
this.ratePerHour = ratePerHour;
}
@Override
long monthlyPay() { return hours * ratePerHour; }
}
public static void main(String[] args) {
Employee[] staff = {
new FullTimeEmployee("Navika", "E101", 85000),
new Contractor("Advitha", "C207", 120, 600)
};
for (Employee e : staff) {
System.out.println(e.payslip());
}
}
}E101 Navika: Rs. 85000
C207 Advitha: Rs. 72000How it works
abstract class Employeecan have fields, a constructor and finished methods, just like a normal class.abstract long monthlyPay();has no body, only a semicolon. It's a blank that subclasses must fill.payslip()is finished code that calls the blank. At runtime, the subclass'smonthlyPay()runs: 120 × 600 = 72,000 for Advitha.- The
Employeeconstructor still runs, throughsuper(name, id), to set up the shared fields.
Try it yourself: add an Intern subclass with a fixed stipend of Rs. 15,000, and add Srihitha as an intern.
The Rules
| Rule | Detail |
|---|---|
Can't use new on it | new Employee(...) is a compile error |
| Can have constructors | They run when a subclass object is created |
| Can have fields, static members and finished methods | Like any class |
| Can have zero abstract methods | Still can't be instantiated; useful for a "base only" class |
| An abstract method has no body | abstract long monthlyPay(); |
| A class with an abstract method must be abstract | Otherwise it's a compile error |
abstract can't combine with final, private or static on a method | Each would make the method impossible to override |
Breaking the rules looks like this:
abstract class Shape { abstract double area(); }
class Circle extends Shape { }
class Use { Shape s = new Shape(); }
abstract final class X {}
class Y { abstract void m(); }E1.java:4: error: illegal combination of modifiers: abstract and final
abstract final class X {}
^
E1.java:2: error: Circle is not abstract and does not override abstract method area() in Shape
class Circle extends Shape { }
^
E1.java:3: error: Shape is abstract; cannot be instantiated
class Use { Shape s = new Shape(); }
^
E1.java:5: error: Y is not abstract and does not override abstract method m() in Y
class Y { abstract void m(); }
^
4 errorsThe Template Method Idea
payslip() above is a template method: the abstract class fixes the steps and the order, and subclasses supply one or more steps. The JDK uses it widely. java.util.AbstractList implements dozens of list methods on top of two abstract ones, get(int) and size(). Write those two and you have a working read-only list.
Common Mistakes
Trying to create the abstract class with new. Create a concrete subclass instead, or an anonymous class (see "Anonymous Inner Class in Java").
Forgetting one abstract method in a subclass. The error names the missing method; implement it or make the subclass abstract.
Calling an abstract method from the constructor. The subclass's fields aren't set yet when it runs, so it can see zeros and nulls.
Interview Corner
Can an abstract class have a constructor?
Yes. It can't be instantiated directly, but its constructor runs whenever a subclass object is created, through super(...), to initialize the fields the abstract class declares.
Can an abstract class have no abstract methods?
Yes. Declaring a class abstract only prevents direct instantiation. It's useful for base classes that should exist only as parents, such as java.util.AbstractList's helpers or framework base classes.
Why can't an abstract method be final, private or static?
An abstract method exists to be overridden. A final method can't be overridden, a private method isn't visible to subclasses, and a static method belongs to the class and isn't overridden, so each combination would make the method impossible to implement.
Practice
- Easy: Create an abstract class
Shapewith an abstractarea()and a finisheddescribe()that prints the area. ImplementCircleandSquare. - Harder: Create an abstract class
Reportwith a finalprint()that callsheader(),body()andfooter(). Makeheader()andfooter()finished andbody()abstract, then writeSalesReportandStockReport.
Key Takeaways
Was this tutorial helpful?