Click here to Skip to main content
15,889,876 members
Articles / Programming Languages / ECMAScript 6

JavaScript ES6 Multiple Inheritance Class

Rate me:
Please Sign up or sign in to vote.
4.23/5 (7 votes)
28 May 2017CPOL 31.1K   3   2
Adds functionality to ES6 for multi inheritance of classes.

Introduction

I decided to jump into JavaScript ES6 and start learning the new features. I like everything except the lack of multiple inheritance support for classes. Having to chain around single classes to make multi inheritance is a pain in the ass. So in an attempt to resolve the problem, I came up with the class below.

Multi Inheritance Class

JavaScript
// Class for creating multi inheritance.
class multi
{
	// Inherit method to create base classes.
	static inherit(..._bases)
	{
		class classes {

			// The base classes
  			get base() { return _bases; }

			constructor(..._args)
			{
				var index = 0;

				for (let b of this.base) 
				{
					let obj = new b(_args[index++]);
   					multi.copy(this, obj);
				}
			}
		
		}

		// Copy over properties and methods
		for (let base of _bases) 
		{
   			multi.copy(classes, base);
   			multi.copy(classes.prototype, base.prototype);
		}

		return classes;
	}

	// Copies the properties from one class to another
	static copy(_target, _source) 
	{
    		for (let key of Reflect.ownKeys(_source)) 
			{
        		if (key !== "constructor" && key !== "prototype" && key !== "name") 
				{
	        	    let desc = Object.getOwnPropertyDescriptor(_source, key);
	        	    Object.defineProperty(_target, key, desc);
        		}
    		}
	}
}

How Does it Work?

In order for multi inheritance to work, I utilized a lot of the new ES6 features in combination with ES5. The class is extended by using the following code.

JavaScript
// Single Inherit
class person extends ages

// Multi Inherit
class person extends multi.inherit(ages, genders)

Instead of passing a class to the extend, we pass a static function called inherit, which returns a class after merging properties and methods together of other named classes. Inside the inherit method, we receive a rest parameter with all class names to inherit from.

JavaScript
// The base classes
get base() { return _bases; }

This is a key feature for creating the instances of each class and copying their properties in the constructor method. We forward the parameters from the super() to the constructor.

JavaScript
constructor(..._args)
{
	var index = 0;

	for (let b of this.base) 
	{
		let obj = new b(_args[index++]);
		multi.copy(this, obj);
	}
}

Below is a full working example of multiple inheritance.

Full Sample Code

JavaScript
// Class for creating multi inheritance.
class multi
{
	// Inherit method to create base classes.
	static inherit(..._bases)
	{
		class classes {

			// The base classes
  			get base() { return _bases; }

			constructor(..._args)
			{
				var index = 0;

				for (let b of this.base) 
				{
					let obj = new b(_args[index++]);
   					multi.copy(this, obj);
				}
			}
		
		}

		// Copy over properties and methods
		for (let base of _bases) 
		{
   			multi.copy(classes, base);
   			multi.copy(classes.prototype, base.prototype);
		}

		return classes;
	}

	// Copies the properties from one class to another
	static copy(_target, _source) 
	{
    		for (let key of Reflect.ownKeys(_source)) 
			{
        		if (key !== "constructor" && key !== "prototype" && key !== "name") 
				{
	        	    let desc = Object.getOwnPropertyDescriptor(_source, key);
	        	    Object.defineProperty(_target, key, desc);
        		}
    		}
	}
}

class ages
{
	constructor(_age) {	this.age = _age; }
	set age(_a) { this._age = _a; }
	get age() { return this._age; }
	increase() { this.age++; }
}

class genders
{
	constructor(_gender) { this.gender = _gender; }
	set gender(_g) { this._gender = _g; }
	get gender() { return this._gender; }
	male() { this._gender = 'M'; }
	female() { this._gender = 'F'; }
}

class person extends multi.inherit(ages, genders)
{
	constructor(...args)
	{
		super(18, 'M');
		this.name = args[0];
	}

	set name(_n) { this._name = _n; }
	get name() { return this._name; }
}

var p = new person('Adam');
console.log(p.name, p.age, p.gender);

History

Version 0.1 - First release of script, needs perfecting.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Codevendor
United States United States
Please visit my personal website https://codevendor.com for my latest codes and updates.

Comments and Discussions

 
QuestionName collision Pin
Daniel Gidman30-May-17 4:41
professionalDaniel Gidman30-May-17 4:41 
AnswerRe: Name collision Pin
M@dHatter30-May-17 10:26
M@dHatter30-May-17 10:26 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.