Interfaces
An interface
is a contract that defines the properties and what the object that implements it can do. For example, you could define what can do a Plumber and an Electrician:
interface Electrician {
layWires(): void
}
interface Plumber {
layPipes(): void
}
Then, you can consume the services of your interfaces:
function restoreHouse(e: Electrician, p: Plumber) {
e.layWires()
p.layPipes()
}
Notice that the way you have to implement an interface is free. You can do that by instantiating a class, or with a simple object:
let iAmAnElectrician = {
layWires: () => { console.log("Work with wires…") }
}
An interface doesn't exist at all at runtime, so it is not possible to make an introspection. It is the classic JavaScript way to deal with object programming, but with a good control at compile time of the defined contracts.
Abstract classes
A class
is both a contract and the implementation of a factory. An abstract class
is also an implementation but incomplete. Especially, an abstract class exists at runtime, even if it has only abstract methods (then instanceof
can be used).
When you define an abstract class, you often try to control how a process has to be implemented. For example, you could write something like this:
abstract class HouseRestorer {
protected abstract layWires(): void
protected abstract layPipes(): void
restoreHouse() {
this.layWires()
this.layPipes()
}
}
This abstract class HouseRestorer
defines how the methods layWires
and layPipes
will be used, but it is up to a child class to implement the specialized treatments before it can be used.
Abstract classes are a traditional OOP approach, which is not traditional in JavaScript.
Both approaches allow the same things to be done. But they are two different ways of solving a problem.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…