Reach for an abstract class when several subclasses genuinely share data or code and you want that sharing enforced by the compiler rather than by team discipline. The Notification family above is exactly that shape.
Skip it when the only thing in common is a method name. Two unrelated classes that each happen to have a send() do not need a parent, and duplicating three lines is cheaper than an inheritance tree nobody asked for.
Signs you are forcing it:
- The abstract class has exactly one subclass and no second one is planned.
- You added a parent only to satisfy a rule of thumb.
- The parent holds no real state, and only method names are being shared. That is an interface wearing a hat.
A useful test: if you cannot complete the sentence "every subclass needs..." with at least one field or one real method, an interface is the better tool.
Frequently Asked Questions
Can we instantiate an abstract class in Java?
No. new AbstractClass() is a compile-time error, reported as "X is abstract; cannot be instantiated". The check happens before the program runs, because the type is deliberately incomplete. To obtain an object, create a concrete subclass and instantiate that, or return one from a factory method.
What is partial implementation in Java?
It is when a class inherits behaviour from a parent and leaves the rest for its children to finish. An abstract class is the tool for it: concrete methods hold the shared part, abstract methods mark what each child must write. In the example above, Notification shares recipient and log() while leaving send() and channel() open.
What is the difference between an abstract class and an incomplete class?
Java has no separate "incomplete class" construct. "Incomplete type" is a descriptive phrase for an abstract class, or for a concrete class whose parent left a method unimplemented. The compiler's job is to guarantee the incompleteness is always resolved somewhere before any object exists.
Can an abstract class have a constructor?
Yes. The constructor initialises state shared by every subclass and is invoked from them through super(...). It is never called on the abstract class itself, because that class cannot be instantiated. It is exactly the feature an interface cannot offer.
Can an abstract class have zero abstract methods?
Yes, and it compiles. The abstract keyword on its own blocks direct construction, which is useful when a class should only ever be obtained through a factory or a static builder.
What happens if a subclass does not implement all abstract methods?
The compiler reports that the class is not abstract and does not override the named method, unless the subclass is itself declared abstract. The obligation then passes to its own subclasses until some concrete class closes every gap.
Why can an abstract method not be private or static?
Because a private method is not inherited, so no child could ever see or replace it, and a static method belongs to the class rather than to instances, so there is no per-object behaviour to supply. javac rejects both as an illegal combination of modifiers.
Is abstract slower than a concrete class at run time?
No. There is no runtime check involved. The completeness requirement is enforced entirely at compile time, and the resulting object behaves exactly like any other. The only cost is a slightly deeper hierarchy, which is irrelevant next to the duplication it removes.
Should I use an empty method body instead of an abstract one?
No. An empty body compiles without complaint and produces a silent no-op at run time, which is far more expensive to find than a compile error. Declare the method abstract so a forgetful subclass fails the build immediately.
Can an abstract class implement an interface?
Yes, and it is common. The abstract class can implement the interface without providing every method, since it is itself abstract and cannot be instantiated anyway. Each concrete subclass then inherits the remaining obligation and must complete it.