Click here to Skip to main content
13,667,632 members
Click here to Skip to main content
Add your own
alternative version

Tagged as

Stats

9.7K views
2 bookmarked
Posted 28 May 2017
Licenced CPOL

JavaScript ES6 Multiple Inheritance Class

, 28 May 2017
Rate this:
Please Sign up or sign in to vote.
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

// 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.

// 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.

// 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.

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

// 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)

Share

About the Author

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

You may also be interested in...

Pro

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
memberM@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.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web01-2016 | 2.8.180820.1 | Last Updated 28 May 2017
Article Copyright 2017 by M@dHatter
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid