skip to content

Why can't you instantiate an abstract class, yet it can still declare constructors and even fields — what role do those play?

level: middleimportance: should knowfreq 58%

answer

  1. new blocked: type may be incomplete
  2. constructor initializes fields, doesn't allocate
  3. subclass super(...) runs base constructor
  4. base fields = shared subclass state
  5. super-first construction order

basics

~20 s

You can't use new on an abstract class because it may have unfinished (abstract) methods, so the object would be incomplete. Its constructor and fields still exist to set up the shared state that subclasses inherit; the subclass constructor calls super(...) to run them.

solid answer

~50 s

`new` is forbidden on an abstract class because the type is deliberately incomplete — it may have abstract methods with no implementation, so a direct instance could have callable methods with no behavior. That's a safety guarantee the compiler enforces. But an abstract class is still a real class in the inheritance chain: it owns instance fields representing shared state and a constructor that initializes them. When you instantiate a concrete subclass, construction walks up the hierarchy — the subclass constructor's first action is an explicit or implicit `super(...)` call, which runs the abstract class's constructor, which initializes the inherited fields, all before the subclass body executes. So the abstract class's constructor never creates a standalone object; it runs *as part of* building a subclass instance. Fields and constructors are how the abstract base contributes its slice of state to every subclass object.

go deeper

for a junior

Knows new is blocked and that constructors/fields still exist; can state the super() linkage at a high level.

for a middle

Explains the super-first construction order and that the base constructor initializes inherited state via super(...).

for a senior

Articulates the construction-order pitfall (overridable method called from constructor) and why abstract classes centralize state interfaces cannot.

for a principal

Discusses initialization-safety invariants, final-field publication, and design rules that keep base constructors from leaking 'this' or invoking overridable hooks.

## The apparent paradox It feels contradictory: a **constructor** is the special method that builds an object, yet an abstract class — which *cannot* be turned into an object via `new` — is allowed to have one. And it can declare **fields** (data slots) even though no standalone instance of it ever exists. Resolving this requires understanding how object construction actually works in an inheritance hierarchy. ## Why instantiation is blocked An abstract class may declare **abstract methods** — methods with a signature but no body. If you could write `new Shape()`, you'd get an object on which calling `area()` would have no code to run. To prevent this whole category of error, Java forbids `new` on *any* abstract class — even one that happens to have no abstract methods. The `abstract` keyword is a blanket 'do not instantiate directly' marker. This is a **compile-time** guarantee: the error happens before the program ever runs. ## What a constructor really does A constructor's job is **not** 'create the object' (the JVM allocates memory) — its job is to **initialize the fields** of one layer of the object. Every object of a subclass type physically contains the fields of *all* its ancestors, laid out together in memory. Each ancestor's constructor is responsible for initializing *its own* fields. ## Construction order: super-first When you write `new Circle(2)` (where `Circle extends Shape` and `Shape` is abstract): 1. The `Circle` constructor begins. Its **very first statement** is a call to a `Shape` constructor — either an explicit `super(...)` you wrote, or an implicit `super()` the compiler inserts. 2. Control jumps *up* to the `Shape` (abstract) constructor, which initializes `Shape`'s fields (the inherited shared state). 3. Control returns *down* to the `Circle` constructor body, which initializes `Circle`'s own fields. So the abstract class's constructor **does** run — but only ever as a sub-step of constructing a *concrete subclass* instance. It never produces a `Shape`-only object. This is exactly why an abstract class needs a constructor: to give subclasses a way (via `super(...)`) to initialize the state the base declares. If the base has a field like `private final String name`, only the base's constructor can set it, so subclasses must funnel a value up through `super(name)`. ## Fields and shared state Fields in the abstract class represent **state common to every subclass**. Putting them in the base means each subclass automatically has them, initialized consistently, with the base's invariants (e.g. validation in the constructor) enforced once. This is the central advantage of an abstract class over an interface: interfaces cannot hold mutable instance state, so they can't centralize shared data this way. ## A subtle hazard Because super-constructors run *before* the subclass body, calling an **overridable (abstract or non-final) method from a base constructor** is dangerous: the subclass's override runs while the subclass's own fields are still at their default values (e.g. `null`, `0`). This 'construction-order pitfall' is why base classes should avoid invoking their own abstract methods during construction.

  • What happens to an abstract class's constructor at runtime if you never subclass it?
    Nothing runs it. A constructor only executes as part of building an instance, and without a concrete subclass no instance is ever created, so the abstract class's constructor is dead code at runtime (though still valid to declare).
  • Why is calling an abstract method from the base-class constructor risky?
    Because super-constructors run before the subclass body, the subclass override executes while the subclass's own fields are still at their default values. The override can observe a half-built object, leading to NullPointerExceptions or wrong behavior.

saying these in an interview costs you the question

  • Saying an abstract class has no constructor because it can't be instantiated.
  • Thinking the base constructor creates a separate base object.
  • Claiming abstract classes can't hold instance fields (they can; interfaces can't).
  • Calling an overridable/abstract method from the base constructor and expecting subclass fields to be set.

context