The abstract keyword marks a class that cannot be instantiated, or a method that has no body and must be implemented by a subclass. An abstract class in Java holds the code that its subclasses share and leaves the varying parts to them as abstract methods.
We use abstract classes to build a family of related types with common state and behavior, such as payment methods that all validate an amount but charge it differently. The JDK uses the same idea in classes such as AbstractList, InputStream and Number.
The following example defines a payment with one shared method and one abstract method.
abstract class Payment {
protected final double amount;
Payment(double amount) {
if (amount <= 0) {
throw new IllegalArgumentException("amount must be positive");
}
this.amount = amount;
}
abstract double fee(); // each payment type decides
double total() {
return amount + fee();
}
}
class CardPayment extends Payment {
CardPayment(double amount) {
super(amount);
}
@Override
double fee() {
return amount * 0.02;
}
}
Payment card = new CardPayment(100);
double total = card.total(); // 102.0
Notice that the abstract class has a constructor and a field, and the subclass only fills in the fee. We go through the rules for abstract classes and methods, which support abstraction, the modifier combinations the compiler rejects, abstract classes compared with interfaces, and sealed abstract hierarchies.
1. Abstract Classes
An abstract class is declared with abstract before class. It can contain everything a normal class can, such as fields, constructors, static methods and concrete methods, but we cannot create an object of it with new.

// does not compile: Payment is abstract; cannot be instantiated
Payment payment = new Payment(50);
The constructor of an abstract class runs when a subclass calls super(). In Payment, it validates the amount once, so no subclass can skip that check, which is a common reason to prefer an abstract class over an interface.
A class does not need any abstract methods to be abstract. Marking a class abstract without abstract methods prevents direct instantiation, as in a base class that only makes sense with a concrete subtype. An anonymous class can still create a one-off subclass when we need it.
Payment voucher = new Payment(20) {
@Override
double fee() {
return 0;
}
};
double voucherTotal = voucher.total(); // 20.0
2. Abstract Methods
An abstract method has a signature and a semicolon instead of a body. Any class that contains an abstract method must itself be abstract, and the first concrete subclass must implement every abstract method it inherits, including those from interfaces.
abstract class Report {
final String render() { // template method
return header() + "\n" + body();
}
String header() {
return "== " + title() + " ==";
}
abstract String title();
abstract String body();
}
class SalesReport extends Report {
String title() {
return "Sales";
}
String body() {
return "Total 1200";
}
}
String text = new SalesReport().render(); // "== Sales ==\nTotal 1200"
The Report class follows the template method pattern. The abstract class fixes the order of steps in a final method, and subclasses provide the steps. A subclass that implements only some of the abstract methods must be declared abstract too.
3. Illegal Combinations with abstract
An abstract method must be overridable, so the compiler rejects every modifier that prevents overriding or that requires a body. The JLS lists these combinations in its section on abstract methods.
| Combination | Allowed | Reason |
|---|---|---|
| abstract and final | No | A final method or class cannot be overridden or extended |
| abstract and private | No | A private method is not visible to subclasses |
| abstract and static | No | Static methods are not overridden, so the method would never get a body |
| abstract and synchronized or native | No | Both describe an implementation, which an abstract method does not have |
| abstract and protected or public | Yes | Subclasses can see and override the method |
| abstract and sealed on a class | Yes | The class limits which classes can extend it |
A subclass can make an inherited method synchronized when it overrides it, because that is a property of the implementation. Fields cannot be abstract, since a field has no behavior to override.
4. Abstract Class vs Interface
Since Java 8, interfaces can have default and static methods, and since Java 9 private methods, so the choice is less obvious than it used to be. The main difference is state, because an interface cannot have instance fields or constructors.
| Feature | Abstract class | Interface |
|---|---|---|
| Instance fields | Yes | No, only constants |
| Constructors | Yes | No |
| Methods with a body | Any kind | default, static and private methods |
| Inheritance | A class extends only one | A class implements many |
| Member visibility | Any | Public, except private methods |
| Typical use | Shared state and code for closely related classes | A capability that unrelated classes can have |
A practical rule is to start with an interface, because it keeps the type flexible, and add an abstract class when several implementations repeat the same fields and logic. The JDK does both, with the List interface and the AbstractList class that implements most of it. The guide to interfaces and abstract classes compares them in more depth.
5. Sealed Abstract Classes
Since Java 17, an abstract class can also be sealed, which lists the only classes allowed to extend it. Combined with pattern matching for switch in Java 21, the compiler checks that a switch handles every subclass.
sealed abstract class Account permits Savings, Checking {
abstract double rate();
}
final class Savings extends Account {
double rate() {
return 0.04;
}
}
final class Checking extends Account {
double rate() {
return 0.0;
}
}
Account account = new Savings();
String kind = switch (account) {
case Savings s -> "savings at " + s.rate();
case Checking c -> "checking";
};
String result = kind; // "savings at 0.04"
The switch has no default case, because the permits list tells the compiler that only two subclasses exist. Adding a third subclass turns every such switch into a compile error until it handles the new type.
6. Abstract Class FAQs
Interviewers and developers ask these questions about abstract classes and methods.
6.1. Can an abstract class have a constructor?
Yes. It runs when a subclass constructor calls super(), and it initializes the shared fields or validates arguments.
6.2. Can an abstract class have a main method?
Yes. A static method, including main(), belongs to the class, not to an object, so it runs without an instance.
6.3. Can we create an object of an abstract class?
Not with new alone. We create an object of a concrete subclass or an anonymous subclass, and the variable can still have the abstract type.
6.4. Can an abstract class implement an interface without implementing its methods?
Yes. The unimplemented interface methods stay abstract, and the first concrete subclass must implement them.
7. Conclusion
The abstract keyword creates classes that cannot be instantiated and methods without a body. Abstract classes can still have fields, constructors and concrete methods, which makes them the right place for state and logic shared by closely related subclasses.
Abstract methods cannot be final, private or static, because subclasses must override them. We prefer interfaces for capabilities, abstract classes for shared state, and sealed abstract classes when the set of subclasses is fixed.
8. References
- JLS 25, abstract Classes
- JLS 25, abstract Methods
- Oracle Java Tutorials, Abstract Methods and Classes
- JEP 409, Sealed Classes
Happy Learning !!