I was surprised that I couldn't find anything about abstract classes when reading up on ES6. (By "abstract class" I'm talking about the Java meaning of it, in which an abstract class declares method signatures that a subclass must implement in order to be instantiable).
Does anyone know of any conventions that have taken hold to implement abstract classes in ES6? It would be nice to be able to catch an abstract class violation with static analysis.
If I were to raise an error at runtime to signal an attempt at abstract class instantiation, what would the error be?
ES2015 does not have Java-style classes with built-in affordances for your desired design pattern. However, it has some options which may be helpful, depending on exactly what you are trying to accomplish.
If you would like a class that cannot be constructed, but whose subclasses can, then you can use new.target
:
class Abstract {
constructor() {
if (new.target === Abstract) {
throw new TypeError("Cannot construct Abstract instances directly");
}
}
}
class Derived extends Abstract {
constructor() {
super();
// more Derived-specific stuff here, maybe
}
}
const a = new Abstract(); // new.target is Abstract, so it throws
const b = new Derived(); // new.target is Derived, so no error
For more details on new.target
, you may want to read this general overview of how classes in ES2015 work: http://www.2ality.com/2015/02/es6-classes-final.html
If you're specifically looking for requiring certain methods be implemented, you can check that in the superclass constructor as well:
class Abstract {
constructor() {
if (this.method === undefined) {
// or maybe test typeof this.method === "function"
throw new TypeError("Must override method");
}
}
}
class Derived1 extends Abstract {}
class Derived2 extends Abstract {
method() {}
}
const a = new Abstract(); // this.method is undefined; error
const b = new Derived1(); // this.method is undefined; error
const c = new Derived2(); // this.method is Derived2.prototype.method; no error