The primary reason to use interfaces to achieve polymorphism and provide developers to implement on their own way in future by implementing interface's methods.
Suppose we have an interface and three classes:
interface Connector{
doConnect(): boolean;
}
This is connector interface. Now we will implement that for Wifi communication.
export class WifiConnector implements Connector{
public doConnect(): boolean{
console.log("Connecting via wifi");
console.log("Get password");
console.log("Lease an IP for 24 hours");
console.log("Connected");
return true
}
}
Here we have developed our concrete class named WifiConnector
that has its own implementation. This is now type Connector
.
Now we are creating our System
that has a component Connector
. This is called dependency injection.
export class System {
constructor(private connector: Connector){ #inject Connector type
connector.doConnect()
}
}
constructor(private connector: Connector)
this line is very important here. Connector
is an interface and must have doConnect()
. As Connector
is an interface this class System
has much more flexibility. We can pass any Type which has implemented Connector
interface. In future developer achieves more flexibility. For example, now developer want to add Bluetooth Connection module:
export class BluetoothConnector implements Connector{
public doConnect(): boolean{
console.log("Connecting via Bluetooth");
console.log("Pair with PIN");
console.log("Connected");
return true
}
}
See that Wifi and Bluetooth have its own implementation. There own different way to connect. However, hence both have implemented Type Connector
the are now Type Connector
. So that we can pass any of those to System
class as the constructor parameter. This is called polymorphism. The class System
is now not aware of whether it is Bluetooth / Wifi even we can add another Communication module like Inferade, Bluetooth5 and whatsoever by just implementing Connector
interface.
This is called Duck typing. Connector
type is now dynamic as doConnect()
is just a placeholder and developer implement this as his/her own.
if at constructor(private connector: WifiConnector)
where WifiConnector
is a concrete class what will happen? Then System
class will tightly couple only with WifiConnector nothing else. Here interface solved our problem by polymorphism.