Abstract Class in Java – Abstract Methods, Rules and Examples
An abstract class is a class declared with the abstract keyword. It cannot be instantiated on its own; it exists to be extended. It can contain abstract methods (declared without a body, which subclasses must implement) alongside ordinary fields, constructors and concrete methods that all subclasses share.
This tutorial covers the syntax and rules of abstract classes and methods, shows constructors, anonymous subclasses and skeletal implementations in action, and explains when an interface is the better choice.
1. Syntax
abstract class ClassName {
// fields, constructors, static members, blocks
// concrete (normal) methods
abstract ReturnType methodName(Parameters); // no body, ends with ;
}
An abstract class can contain everything a normal class can, plus abstract methods. If a class has even one abstract method, it must be declared abstract.
2. A Complete Example
Every employee has a name and a payslip, but each type calculates monthly pay differently:
public class AbstractClassBasics {
static abstract class Employee {
private final String name; // fields
protected final double baseSalary;
private static int count = 0;
Employee(String name, double baseSalary) { // constructor
this.name = name;
this.baseSalary = baseSalary;
count++;
System.out.println("Employee constructor ran for " + name);
}
abstract double monthlyPay(); // abstract: no body
String payslip() { // concrete method using the abstract one
return String.format("%-6s %-10s %,10.2f", name, getClass().getSimpleName(), monthlyPay());
}
static int count() { return count; } // static method
}
static class FullTime extends Employee {
FullTime(String name, double salary) { super(name, salary); }
@Override double monthlyPay() { return baseSalary / 12; }
}
static class Contractor extends Employee {
private final int hours;
Contractor(String name, double hourlyRate, int hours) { super(name, hourlyRate); this.hours = hours; }
@Override double monthlyPay() { return baseSalary * hours; }
}
public static void main(String[] args) {
Employee[] staff = { new FullTime("Asha", 1_200_000), new Contractor("Ravi", 900, 120) };
System.out.println();
for (Employee e : staff) System.out.println(e.payslip());
System.out.println("Employees created: " + Employee.count());
}
}
Employee constructor ran for Asha Employee constructor ran for Ravi Asha FullTime 100,000.00 Ravi Contractor 108,000.00 Employees created: 2
Employeehas fields, a constructor, a static method and a concretepayslip()method.monthlyPay()is abstract; each subclass provides its own formula.payslip()callsmonthlyPay(), and polymorphism picks the right version at run time.- The abstract class's constructor runs, through
super(...), every time a subclass object is created.
3. Abstract Methods
An abstract method declares the signature (return type, name, parameters and optional throws clause) and ends with a semicolon:
abstract class Order {
abstract String summary(int orderId) throws OrderNotFoundException; // OK
}
class Invoice {
abstract void print(); // compile error: Invoice is not abstract
}
abstract class Bad {
private abstract void a(); // error: private methods cannot be overridden
static abstract void b(); // error: static methods cannot be overridden
final abstract void c(); // error: final methods cannot be overridden
}
4. Instantiating Through Anonymous Subclasses
new Greeter() is illegal for an abstract class, but an anonymous class that implements the abstract methods is allowed:
public class AnonymousSubclass {
static abstract class Greeter {
abstract String greet(String name);
void welcome(String name) { System.out.println(greet(name) + " Welcome to JavaByTechie."); }
}
public static void main(String[] args) {
// An abstract class cannot be instantiated, but an anonymous subclass can be
Greeter hindi = new Greeter() {
@Override String greet(String name) { return "Namaste, " + name + "!"; }
};
hindi.welcome("Asha");
System.out.println("Actual class is anonymous: " + hindi.getClass().isAnonymousClass());
}
}
Namaste, Asha! Welcome to JavaByTechie. Actual class is anonymous: true
5. Partially Implementing an Abstract Class
A subclass that does not implement every abstract method must itself be declared abstract. The chain ends with a concrete class that completes the contract:
public class AbstractChain {
static abstract class Vehicle {
abstract int wheels();
abstract String fuel();
}
// Still abstract: implements only part of the contract
static abstract class Car extends Vehicle {
@Override int wheels() { return 4; }
}
static class ElectricCar extends Car {
@Override String fuel() { return "electricity"; }
}
public static void main(String[] args) {
Vehicle v = new ElectricCar();
System.out.println("Wheels: " + v.wheels() + ", fuel: " + v.fuel());
}
}
Wheels: 4, fuel: electricity
6. Abstract Class + Interface: Skeletal Implementation
A powerful pattern is to define the contract as an interface and provide an abstract class that implements the shared parts. The JDK does this with List/AbstractList and Map/AbstractMap:
public class AbstractWithInterface {
interface PaymentMethod {
boolean pay(double amount);
}
// Skeletal implementation: shared validation and logging, one step left abstract
static abstract class AbstractPayment implements PaymentMethod {
@Override
public final boolean pay(double amount) {
if (amount <= 0) {
System.out.println("Invalid amount: " + amount);
return false;
}
boolean ok = process(amount);
System.out.println(getClass().getSimpleName() + " " + amount + " -> " + (ok ? "SUCCESS" : "FAILED"));
return ok;
}
protected abstract boolean process(double amount);
}
static class UpiPayment extends AbstractPayment {
protected boolean process(double amount) { return true; }
}
static class CardPayment extends AbstractPayment {
protected boolean process(double amount) { return amount <= 50_000; } // card limit
}
public static void main(String[] args) {
PaymentMethod upi = new UpiPayment(), card = new CardPayment();
upi.pay(1_499);
card.pay(75_000);
card.pay(-5);
}
}
UpiPayment 1499.0 -> SUCCESS CardPayment 75000.0 -> FAILED Invalid amount: -5.0
The final pay method is a template method: validation and logging are fixed, and only process varies.
7. Rules of Abstract Classes
- Declared with the
abstractkeyword; cannot be instantiated withnew. - Can have zero or more abstract methods, and any number of concrete methods.
- Can have constructors, instance and static fields, static methods, and initializer blocks.
- Can have members with any access modifier, unlike interface methods.
- A concrete subclass must implement all inherited abstract methods.
- Cannot be
final, because it must be extendable. - Can implement interfaces without implementing their methods; subclasses complete them.
- Can be used as a reference type:
Employee e = new FullTime(...);
8. Abstract Class vs Interface
| Aspect | Abstract class | Interface |
|---|---|---|
| Methods | Abstract and concrete | Abstract, default, static and private |
| Fields | Any instance or static fields | Only public static final constants |
| Constructors | Yes | No |
| Inheritance | A class extends only one | A class implements many |
| Access modifiers | Any | Members are public (private helper methods allowed) |
| Best for | Related classes sharing state and code | Capabilities shared by unrelated classes |
Read the full comparison in Abstract Class vs Interface.
9. Summary
- An abstract class is declared with
abstractand cannot be instantiated. - Abstract methods have no body and must be implemented by concrete subclasses.
- Abstract classes can have fields, constructors and concrete methods shared by subclasses.
- Abstract methods cannot be private, static or final; an abstract class cannot be final.
- Combine an interface with an abstract skeletal implementation for flexible, reusable designs.
Related Tutorials
Frequently Asked Questions (FAQ)
Q1. What is an abstract class in Java?
A class declared with abstract that cannot be instantiated and is meant to be extended. It can contain abstract and concrete methods.
Q2. Can we create an object of an abstract class?
Not directly. You create objects of concrete subclasses, or of an anonymous subclass that implements the abstract methods.
Q3. Can an abstract class have a constructor?
Yes. It is called through super(...) when a subclass object is created and initialises the abstract class's fields.
Q4. Can an abstract class have no abstract methods?
Yes. It is then abstract only to prevent direct instantiation.
Q5. Can an abstract class have a main method?
Yes. main is static, so it can run without creating an instance of the abstract class.
Q6. Can an abstract class be final?
No. final prevents extension, but an abstract class is useless unless extended. The compiler rejects the combination.
Q7. Can an abstract method be static?
No. Static methods are not overridden, so an abstract static method could never be implemented.
Q8. Can an abstract method be private?
No. Private methods are not visible to subclasses and cannot be overridden.
Q9. What happens if a subclass does not implement all abstract methods?
It must be declared abstract itself; otherwise compilation fails.
Q10. Can an abstract class implement an interface?
Yes, and it need not implement the interface's methods. Concrete subclasses must implement whatever remains.
Q11. Can an abstract class extend a concrete class?
Yes. For example, every abstract class implicitly extends Object, and it can extend any non-final class.
Q12. Can an abstract class have static methods and fields?
Yes. They are called with the class name, like in any class.
Q13. Can an abstract method throw exceptions?
Yes, it can declare a throws clause. Overriding methods may throw the same, narrower or fewer checked exceptions.
Q14. What is the difference between an abstract class and a concrete class?
A concrete class can be instantiated and has bodies for all its methods. An abstract class cannot be instantiated and may contain abstract methods.
Q15. When should I use an abstract class instead of an interface?
When closely related classes share state (fields), constructors or non-public methods, or when you want to fix part of an algorithm in a template method.
Q16. Can an abstract class have final methods?
Yes. Final concrete methods cannot be overridden by subclasses, which is common for template methods.
Q17. Can we declare an abstract class reference?
Yes. Employee e = new FullTime(...) is valid and enables polymorphism.
Q18. Which JDK classes are abstract?
Number, InputStream, OutputStream, Reader, Writer, AbstractList, AbstractMap and Calendar are common examples.
Q19. Can an abstract method be synchronized?
No. synchronized describes how a method body runs, and abstract methods have no body. Implementations can be synchronized.
Q20. Can a sealed class be abstract?
Yes. A sealed abstract class (Java 17+) restricts which classes may extend it, which works well with pattern matching in switch.