abstract class

A base class you can’t create directly, with methods for its descendants to fill in.

On this page

Example

#
TypeScript
abstract class Exercise {
  constructor(public title: string) {}

  abstract check(answer: string): boolean

  run(answer: string): string {
    return `${this.title}: ${this.check(answer) ? 'correct' : 'try again'}`
  }
}

class QuestionExercise extends Exercise {
  constructor(title: string, private correct: string) {
    super(title)
  }

  check(answer: string): boolean {
    return answer.trim().toLowerCase() === this.correct
  }
}

const task = new QuestionExercise('Paragraph tag', 'p')
console.log(task.run(' P '))
console.log(task.run('div'))
Result
Paragraph tag: correct
Paragraph tag: try again

Definition and usage

#

An abstract class is a template for other classes. You can’t create an instance of it with new, you can only extend it. It can contain ordinary methods with code, as well as abstract methods that only have a signature.

Every derived class must implement all the abstract methods. The compiler enforces this, so shared logic stays in the base class, and the details stay in the descendants.

Unlike an interface, an abstract class can contain working code and fields. If you only need a contract with no implementation, an interface is enough.

Syntax

#
Syntax
abstract class Name {
  abstract method(): type
  ordinaryMethod() { … }
}

More examples

#
You can’t create an instance of an abstract class
TypeScript
const generic = new Exercise('Something')
// Error: Cannot create an instance of an abstract class.

Good practices

#
  • An abstract class works well when descendants share a lot of common code. For just a contract, choose an interface.
  • Don’t build long inheritance chains. Composing functions or objects is often simpler.

Related entries

#

Spotted a mistake or missing an example? Write to us.