Skip to content

Instantly share code, notes, and snippets.

@Uplink03
Last active February 14, 2024 04:51
Show Gist options
  • Save Uplink03/18432a00d52e10671eeed0e6f29ebed7 to your computer and use it in GitHub Desktop.
Save Uplink03/18432a00d52e10671eeed0e6f29ebed7 to your computer and use it in GitHub Desktop.
Abstract class pattern in Javascript
// this is an "abstract class" pattern for Javascript
/*
extend `AbstractClass` (meta-class?) to declare your class abstract
define an `abstractMethods()` method in your abstract class to declare which methods child classes must implement
extend your abstract class as normal
*/
// the `AbstractClass` meta-class
class AbstractClass {
static abstractMethods() { return []; }
constructor(className) {
if (this.constructor === AbstractClass || this.constructor === className) {
throw new TypeError(
`Cannot instantiate abstract class "${this.constructor.name}".`,
);
}
let errors = [];
for (let method of className.abstractMethods()) {
if (typeof this[method] !== "function") {
errors.push(new TypeError(`Missing abstract method ${method}`));
}
}
if (errors.length > 0) {
throw new AggregateError(
errors,
`Incomplete implementation of abstract methods in "${this.constructor.name}"`,
);
}
}
}
// an abstract class with two abstract methods: `default` and `documentation`
class Atom extends AbstractClass {
// add list of abstract methods
static abstractMethods() {
return super.abstractMethods().concat(["default", "documentation"]);
}
constructor() {
// run the abstract class checks
super(Atom);
}
}
// a class the extends the abstract class and implements the required methods
class ImplementationOfAnAtom extends Atom {
default() { return "default"; }
documentation() { return "documentation"; }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment