Back to Abstraction & Interfaces
Q3Question 3 of 4

Can you instantiate an abstract class?

Key Concepts
  • No: new AbstractClass() is a compile error because abstract classes have unimplemented methods
  • Yes: new AbstractClass() { implement methods here } creates an anonymous subclass that compiles and runs
  • The anonymous subclass must implement all abstract methods inline in the curly braces
  • Lambda expressions (Java 8) replaced anonymous classes for functional interfaces (one abstract method)
  • Anonymous classes are still needed for abstract classes and interfaces with multiple abstract methods
  • Anonymous classes have their own this reference and can have instance fields, unlike lambdas

Definition

new AbstractClass() is a compile error. new AbstractClass() { implement abstract methods here } creates an anonymous subclass. Lambda replaced anonymous for single-method interfaces. Anonymous is still needed for abstract classes and multi-method interfaces.

You cannot instantiate an abstract class directly because it has unimplemented methods.

  • Direct instantiation: new Account() on an abstract Account is a compile error.
  • Anonymous subclass: new Account("id", balance) { @Override calculateInterest() { return ZERO; } } creates an unnamed class that extends Account, implements all abstract methods, and is instantiated in one expression.
  • Lambda (Java 8): replaced anonymous classes for functional interfaces (one abstract method). (a, b) -> a.compareTo(b) is shorter than new Comparator<>() { @Override int compare(...) { ... } }.
  • Lambda limitation: lambdas cannot replace anonymous subclasses for abstract classes (which have constructors and fields) or interfaces with multiple abstract methods.
  • Anonymous class features: has its own this reference, can have instance fields, generates a separate .class file.

An abstract class is like a blank form template at National Bank of India. You cannot submit a blank form (cannot instantiate). You must fill in the blanks (implement abstract methods). Anonymous subclass means filling in the blanks right there on the spot. Named subclass means taking the form home (creating a separate class), filling it in, and bringing it back later. Both produce a valid, complete form.

Understanding the Concepts

Can you instantiate an abstract class?

No. But you can create an anonymous subclass that implements all abstract methods inline.

What happens when you try to instantiate directly?

JAVA
package com.bank.core;

import java.math.BigDecimal;

public abstract class Account {
    private final String accountId;
    protected BigDecimal balance;

    protected Account(String accountId, BigDecimal balance) {
        this.accountId = accountId;
        this.balance = balance;
    }

    public abstract BigDecimal calculateInterest();
    public abstract String getType();
}

// Compile error:
// Account account = new Account("SAV001", BigDecimal.ZERO);
// "Cannot instantiate the type Account"

How do you create an anonymous subclass?

JAVA
// Named subclass (separate class file):
public class SavingsAccount extends Account {
    public SavingsAccount(String id, BigDecimal bal) { super(id, bal); }
    @Override public BigDecimal calculateInterest() { return balance.multiply(new BigDecimal("0.04")); }
    @Override public String getType() { return "SAVINGS"; }
}
Account named = new SavingsAccount("SAV001", new BigDecimal("125000"));

// Anonymous subclass (inline, no separate class file):
Account anonymous = new Account("ANON001", new BigDecimal("50000")) {
    @Override
    public BigDecimal calculateInterest() {
        return getBalance().multiply(new BigDecimal("0.03"));
    }

    @Override
    public String getType() {
        return "ANONYMOUS";
    }
};
// anonymous.getClass().getSimpleName() -> "" (empty: truly anonymous)
// anonymous.getClass().getName() -> "com.bank.Main$1" (compiler-generated)

When did lambda replace anonymous classes?

JAVA
// Before Java 8: anonymous class for Comparator
java.util.Comparator<Trade> oldWay = new java.util.Comparator<Trade>() {
    @Override
    public int compare(Trade a, Trade b) {
        return a.getAmount().compareTo(b.getAmount());
    }
};

// After Java 8: lambda for functional interface (one abstract method)
java.util.Comparator<Trade> newWay = (a, b) -> a.getAmount().compareTo(b.getAmount());

// Lambda does NOT work for abstract classes:
// Account lambda = (id, bal) -> { ... }; // compile error: not a functional interface

When are anonymous subclasses still useful?

JAVA
// 1. Abstract class: lambda does not work
Account testAccount = new Account("TEST", BigDecimal.ZERO) {
    @Override public BigDecimal calculateInterest() { return BigDecimal.ZERO; }
    @Override public String getType() { return "TEST"; }
};
// Useful in tests: quick one-off implementation without a full class file.

// 2. Interface with multiple abstract methods: lambda does not work
interface TradeValidator {
    boolean validateAmount(BigDecimal amount);
    boolean validateSymbol(String symbol);
}
TradeValidator validator = new TradeValidator() {
    @Override public boolean validateAmount(BigDecimal amount) { return amount.signum() > 0; }
    @Override public boolean validateSymbol(String symbol) { return symbol != null; }
};

// 3. Need instance state inside the anonymous class
java.util.Comparator<Trade> withState = new java.util.Comparator<Trade>() {
    private int compareCount = 0; // state: lambda cannot have instance fields
    @Override public int compare(Trade a, Trade b) {
        compareCount++;
        return a.getAmount().compareTo(b.getAmount());
    }
};

How do anonymous classes compare to lambdas?

| Aspect | Anonymous Class | Lambda |
|--------|----------------|--------|
| Works for | Any interface or abstract class | Functional interface only (one abstract method) |
| this keyword | Refers to anonymous class instance | Refers to enclosing class |
| Instance fields | Can have | Cannot |
| .class file | Generates separate file (Main$1.class) | Uses invokedynamic (no .class file) |
| Verbosity | 5+ lines | 1 line |

What are common mistakes?

The most common mistake is trying to use a lambda for an abstract class or a multi-method interface.

JAVA
// WRONG: lambda for abstract class
// Account a = () -> BigDecimal.ZERO; // compile error

// WRONG: lambda for multi-method interface
// TradeValidator v = (amount) -> amount.signum() > 0; // compile error: two abstract methods

What should a senior engineer know?

  • Anonymous subclasses are used extensively in test fixtures: quick one-off implementations of abstract classes without creating dedicated test doubles.
  • In Spring, anonymous implementations are used in configuration classes for customizing beans inline.
  • Records cannot be anonymous because they are implicitly final.

Visual Overview

DIAGRAM
  ABSTRACT CLASS INSTANTIATION
  ──────────────────────────────────────────

  new Account()          -> COMPILE ERROR
  (cannot instantiate abstract)

  new Account() {        -> ANONYMOUS SUBCLASS
    @Override methods()    (compiler generates Main$1.class)
  };

  new SavingsAccount()   -> NAMED SUBCLASS
  (separate .java file)

  LAMBDA vs ANONYMOUS
  ──────────────────────────────────────────
  Functional interface (1 method) -> use lambda
  Abstract class                  -> must use anonymous
  Interface (2+ methods)          -> must use anonymous
  Need instance fields            -> must use anonymous

Key Takeaway

You cannot instantiate an abstract class directly: new Account() is a compile error because abstract classes have unimplemented methods. But you can create an anonymous subclass that provides implementations inline: new Account(id, balance) { @Override calculateInterest() { ... } }. The compiler generates an unnamed class that extends the abstract class, implements all abstract methods, and is instantiated immediately.

Before Java 8, anonymous classes were the primary way to provide on-the-fly implementations. Lambdas (Java 8) replaced this for functional interfaces (one abstract method). But lambdas cannot replace anonymous subclasses for abstract classes (which have constructors, fields, and multiple abstract methods) or interfaces with multiple abstract methods. Anonymous classes are still used in test fixtures, event handlers, and configuration customization.

Remember one sentence: you cannot instantiate an abstract class, but you can create an anonymous subclass inline, and lambdas only replace anonymous classes for functional interfaces with one abstract method.

---

Share
Use ← → arrow keys to navigate