Multiple Inheritance
And
TypeScript Interfaces
Multiple Inerhitance
Just like it sounds..one object's prototype inheriting from multiple other objects prototoypes.
JavaScript doesn't natively support multiple inheritance, but we can use a design pattern called a mixin.
A mixin you say?
A mixin is a design pattern where you iterate over multiple objects properties to combine them into a single new object.
function extend(destination, source) {
for (var k in source) {
if (source.hasOwnProperty(k)) {
destination[k] = source[k];
}
}
return destination;
}
And now you have multiple inheritance.
This method allows us to inherit from (extend) as many other object's as we want.
function extend(destination, source) {
for (var k in source) {
if (source.hasOwnProperty(k)) {
destination[k] = source[k];
}
}
return destination;
}
function Taco(){
}
Taco.prototype.eat = function(){
/*do stuff*/
};
function Beans(){
}
Beans.prototype.cook = function(){
/*do stuff*/
};
function Guacomole(){
}
Guacomole.prototype.spread = function(){
/*do stuff*/
};
extend(Taco.prototype, Beans);
console.log(Taco);
By using the extend function to implement the mixin pattern we created references to the super prototype methods.
Also notice that we don't inherit a constructor with the mixin
Since we're adding methods to the objects existing prototype, without Object.create() to assign a new prototype object, the constructor remains intact.
var canFly = function() {
this.price = 9.99;
this.takeOff = function() {
//fly baby
};
return this;
};
var isSubmersible = function() {
this.oxygenTanks = 4;
this.dive = function() {
//go deep
};
return this;
}
var Car = function(opts) {
this.wheels = 4;
if (opts.fly) {
canFly.call(Car.prototype);
}
if (opts.swim) {
isSubmersible.call(Car.prototype);
}
};
var flyingSubmaringCar = new Car({ fly : true, swim : true });
console.log(flyingSubmaringCar);
"A mixin should be a process not an object"
Although this achieves multiple inheritance best practice says:
"Something that adds behavior"
Interfaces (TypeScript)
Mixins allowed us to inherit behavior from multiple objects...
...Interfaces allow us to define a contract.
If any object implements an interface it must provide certain behavior and properties
If you wanna be in the band, you gotta wear the makeup bro...
Easiest Way To Remember Interfaces
//we could define an interface for a Car class such that
//every car must have an engine and a color like this:
interface ICar{
engine: string;
color: string;
}
//The Car class adheres to the interface ICar because it implements ICar
class Car implements ICar {
constructor (public engine: string, public color: string) {
}
}
//Create a new instance of a car and fulfills all requirements of the ICar interface 'contract'
var hondaAccord = new Car('V6', 'green');
alert(hondaAccord.engine);
Remember an interface is "just a contract".
By abiding by the contract your object will implement all the requirements of the contract
class Car {
private _basePrice: number;
engine: IEngine;
constructor(options: IAutoOptions) {
this._basePrice = options.basePrice;
this.engine = options.engine;
}
drive() : number {
console.log('driving');
return 1000;
}
get price(): number {
return this._basePrice;
}
set price(value: number) {
this._basePrice = value;
}
}
Implementing interfaces on subclasses
interface IEngine {
start() : void;
stop() : void;
}
interface IAutoOptions {
engine: IEngine;
basePrice: number;
}
interface ICanFly {
altitude: number;
fly() : void;
}
class FlyingEngine implements IEngine {
start() : void { }
stop() : void { }
}
class FlyingCar extends Car implements ICanFly {
altitude: number;
constructor(options: IAutoOptions){
super(options);
this.altitude = 0;
};
fly() : void {
this.engine.start();
console.log('flying');
}
}
//Create a new flying car
var fc = new FlyingCar({basePrice: 1000,
engine: new FlyingEngine()})
alert(fc.price); //[Alert] 1000
class Bird implements ICanFly {
name: string;
altitude: number;
constructor (name: string){
this.name = name;
this.altitude = 100;
};
fly() : void {
console.log('flying');
}
}
var fc = new FlyingCar({basePrice: 1000, engine: new FlyingEngine()})
var tweety = new Bird('Tweety');
var polly = new Bird('Polly');
var flyingThings: Array<ICanFly> = [fc, tweety, polly];
for (var i=0; i< flyingThings.length; i++) {
alert(flyingThings[i].altitude);
}
Verifying type with implementations
Resources
Copy of Multiple Inheritance
By Ray Farias
Copy of Multiple Inheritance
- 1,443