Alternative Inheritance Paradigms - Java Script

Due to the limitations of ECMAScript inheritance (for instance, lack of a private scope and the inability to easily access superclass methods),developers around the world have constantly pushed their code to the limit in an effort to create other ways of implementing inheritance.

zInherit

Prototype chaining essentially copies all methods from an object to a class’s prototype object. But what if there were a different way to accomplish this? There is.Using the zInherit library,it’s possible to accomplish method inheritance without using prototype chaining.This small library supports all modern browsers (Mozilla, IE, Opera, Safari) as well as some older browsers (Netscape 4.x, IE/Mac).

The zInherit library adds two methods to the Object class: inheritFrom() and instanceOf().As you may have guessed, the inheritFrom() method does the heavy lifting,copying the methods from a given class. The following line uses prototype chaining to inherit methods from ClassA to ClassB:

ClassB.prototype = new ClassA();

This line can be replaced with the following:

ClassB.prototype.inheritFrom(ClassA);

The inheritFrom() method accepts one argument, which is the class from which to copy the methods. Note that, as opposed to prototype chaining, this paradigm doesn’t actually create a new instance of the class to inherit from, making it a little safer and freeing the developer from worrying about the constructor arguments.

The instanceOf() method is a replacement for the instanceof operator. Because this paradigm doesn’t use prototype chaining at all, this line of code won’t work:

ClassB instanceof ClassA

The instanceOf() method makes up for this loss, working with inheritFrom() to keep track of all
superclasses:

ClassB.instanceOf(ClassA);

Polygons revisited

The entire polygon example can be rewritten using the zInherit library by replacing just two lines (highlighted):

To test this code, you can use the same example as before and add in a couple extra lines to test out the instanceOf() method:

Dynamic prototyping support

As mentioned earlier, prototype chaining can’t be used in the true spirit of dynamic prototyping, which is to keep all code for a class inside of its constructor. The zInherit library fixes this problem by allowing the inheritFrom() method to be called from inside the constructor.

Take a look at the polygon dynamic prototyping example used earlier, now with the addition of the zInherit library:

The two highlighted lines in the previous code implement inheritance from the Polygon class for both the Triangle and the Rectangle classes. The reason this works is that the prototype object isn’t being overwritten when using the inheritFrom() method; methods are just being added to it. Using this method, it’s possible to get around the prototype chaining restriction and implement dynamic prototyping the way it is intended.

Multiple Inheritance support

One of the most useful features of the zInherit library is its capability to support multiple inheritance, which is not available using prototype chaining. Again, the key fact that makes this possible is that inheritFrom() doesn’t replace the prototype object.

The inheritFrom() method must be used in combination with object masquerading in order to inherit properties and methods. Consider the following example:

Both ClassX and ClassY are small classes, each with one property and one method. Suppose you now have ClassZ that needs to inherit from both. The class can be defined like this:

Note that two lines inherit the properties (using the apply() method), and two lines inherit the methods (using the inheritFrom()) method. As discussed earlier, the order in which the inheritance happens is important, and it is generally better to always inherit methods in the same order as the properties (meaning that if properties are inherited from ClassX and then ClassY, the methods should be inherited in that same order).

The following code tests the multiple inheritance example:

The previous code calls three methods:

  1. sayMessageX(), which is inherited from ClassX, accesses the messageX property, also inherited from ClassX.
  2. sayMessageY(), which is inherited from ClassY, accesses the messageY property, also
    inherited from ClassY.
  3. sayMessageZ(), which is defined in ClassZ, accesses the messageZ property, also defined in ClassZ.

These three methods should output the appropriate message from the appropriate property, indicating that the multiple inheritance has succeeded.

xbObjects

Netscape’s DevEdge site (http://devedge.netscape.com) contains a lot of useful information and scripting tools for Web developers. One such tool is xbObjects written by Bob Clary of Netscape Communications in 2001, when Netscape 6 (Mozilla 0.6) was first released. It supports all versions of Mozilla since that time as well other modern browsers (IE, Opera, Safari).

Purpose

The purpose of xbObjects is to provide a stronger object-oriented paradigm to JavaScript, allowing not only for inheritance but also for overloading of methods and the capability to call superclass methods. To do this, xbObjects requires a number of steps be followed.

First, you must register the class, and in doing so, define which class to inherit from. This is done using
the following call:

_classes.registerClass(“Subclass_Name”,“Superclass_Name”);

Here, the subclass and superclass names are passed in as strings, not as pointers to their constructors. This call must come before the constructor for the given subclass.

The second step is to call the defineClass() method inside of the constructor, passing in the name of the class as well as a pointer to what Clary calls a prototype function, which is used to initialize all properties and methods for the object (more on that later). For example:

As you can see, the prototype function (aptly named prototypeFunction()) is located inside of the constructor. Its main purpose is to assign all methods to the class when appropriate (it works like dynamic prototyping in this way).

The next step (that’s three so far) is to create an init() method for the class. This method is responsible for setting up all properties for the class and must accept the same arguments as the constructor itself. By convention, the init() method is always called after the defineClass() method is called. For example:

You may have noticed a method named parentMethod() being called in the init() method. This is the way that xbObjects allows a class to call a superclass method. The parentMethod() accepts any number of arguments, but the first argument is always the name of the parent class method to call (this argument must be a string, not a function pointer); all other arguments are passed to the superclass method.

In this case, the superclass init() method is being called first, which is required for xbObjects to work. Even though ClassA didn’t register a superclass, a default superclass for all classes is created using xbObjects, which is where this superclass init() method comes from.

The fourth and final step is to add the other class methods inside of the prototype function:

Then, you can create an instance of ClassA in the normal way:

Polygons reloaded

At this point, surely you’re wondering if you will have a chance to see the polygon example redone using xbObjects, so here it goes.First, rewrite the Polygon class, which is very simple:

Next, rewrite the Triangle class, which is the first taste of real inheritance in this example:

Note the registerClass() call just before the constructor, where the inheritance relationship is set up. Also, the first line of the init() method calls the superclass (Polygon) init() with an argument of 3, which sets the sides property to 3. Other than that, the init() method is very similar: a simple constructor, assigning the base and height. The Rectangle class ends up looking very similar to Triangle:

The main difference between this and the Triangle class (aside from the different registerClass() and defineClass() calls) is calling the superclass init() method with an argument of 4. Other than that, the additional length and width properties are added and the getArea() method is overridden.


All rights reserved © 2018 Wisdom IT Services India Pvt. Ltd DMCA.com Protection Status

Java Script Topics