Multiple inheritance is a behavior when a single class extends the functionality of multiple parent classes. For example, an alarm-clock has the properties of both a clock and an alarm. The desired situation is that the parent classes handle the distinct behaviors without needing to know about each other. For an alarm-clock, this means that the clock class will track time, the alarm class would make an alarm action, and the alarm-clock class would allow different events to be set at specific times of the clock.
Many OOP languages support multiple inheritance either directly (C++) or through some other mechanism (Java Interfaces, Objective-C Protocols). How can this be implement in JavaScript. Enter jQuery.
jQuery has this baller function, $.extend. It receives n arguments ( $.extend(arg0, arg1, …., argN); ) and all the members of argN are copied to arg(N-1), then from arg(N-1) to arg(N-2), and so on down the line. This is perfect for creating options for jQuery parameters. However, it can also be used to implement Multiple Inheritance for javascript objects.
Lets check out a very simple, snarky alarm clock.
//create parent Alarm Alarm = function(){}; //with one instance method Alarm.prototype.ring = function(){ console.log("AAAAAHHHHHHHH"); } //create parent Clock Clock = function(){}; //with one instance method Clock.prototype.time = function(){ console.log("is an illusion"); } //create child AlarmClock = function(){}; //inherit from A and B AlarmClock.prototype = $.extend(new Clock(), new Alarm()); // BOOM! c = new AlarmClock(); c.ring();//AAAAAHHHHHHHH c.time();//is an illusion
Pretty cool. However, multiple inheritance presents situations that single inheritance doesn't. What happens if parent classes contain identically named methods? In $.extend the right hand parameter overrides the one to its left. So, if ClassA and ClassB have identically named methods, then ClassB's will override ClassA's.
Lets see this in action.
//create parent with cry Human = function(){}; Human.prototype.cry = function(){ console.log("OUCH!!!"); } //create another parent, also with cry SpaceMarine = function(){}; SpaceMarine.prototype.cry = function(){ console.log("FOR THE EMPEROR!"); }; //inherit from both parents Character = function(){}; Character.prototype = $.extend(new Human(), new SpaceMarine()); // BOOM! c = new Character(); c. cry(); //FOR THE EMPEROR! //cry is inherited from SpaceMarine
Multiple inheritance also evokes an interesting question for object type. What is the object type of ClassC? In this case only the leftmost parent class passes on its type.
ClassC = function(){}; ClassC.prototype = $.extend(new ClassA(), new ClassB()); // BOOM! var c = new ClassC(); console.log(c instanceof ClassA); //true console.log(c instanceof ClassB); //false
This technique requires some function to duplicate properties and methods from object to object. I use jQuery.extend, because I use jQuery it on most projects, but there could be alternatives out there, and it would be simple to create a rudimentary replacement.
Multiple inheritance is especially useful with protocols. For example, a single class to provide data for and respond to interaction with a datalist, ala UIKit's UITableViewDataSource and UITableViewDelegate. To allow a single object to perform two distinct tasks, some form of multiple inheritance must be used.
BOOM!
ReplyDeleteSuper!
ReplyDelete