Using xbObjects to build three-level inheritance : Inheritance « Object Oriented « JavaScript Tutorial

JavaScript Tutorial
1. Language Basics
2. Operators
3. Statement
4. Development
5. Number Data Type
6. String
7. Function
8. Global
9. Math
10. Form
11. Array
12. Date
13. Dialogs
14. Document
15. Event
16. Location
17. Navigator
18. Screen
19. Window
20. History
21. HTML Tags
22. Style
23. DOM Node
24. Drag Drop
25. Object Oriented
26. Regular Expressions
27. XML
28. GUI Components
29. Dojo toolkit
30. jQuery
31. Animation
32. MS JScript
Java
Java Tutorial
Java Source Code / Java Documentation
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
JavaScript Tutorial » Object Oriented » Inheritance 
25. 9. 13. Using xbObjects to build three-level inheritance
<html>
<head>
<title>Example</title>
<script type="text/javascript">
/*
 * xbObjects.js
 * $Revision: 1.2 $ $Date: 2003/02/07 16:04:20 $
 */

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Bob Clary code.
 *
 * The Initial Developer of the Original Code is
 * Bob Clary.
 * Portions created by the Initial Developer are Copyright (C) 2000
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s): Bob Clary <bc@bclary.com>
 *
 * ***** END LICENSE BLOCK ***** */

/*
ChangeLog: 2001-12-19 - bclary - changed xbException init method to
           remove possible exception due to permission denied issues
           in gecko 0.9.5+
*/

function _Classes()
{
  if (typeof(_classes!= 'undefined')
    throw('Only one instance of _Classes() can be created');

  function registerClass(className, parentClassName)
  {
    if (!className)
      throw('xbObjects.js:_Classes::registerClass: className missing');

    if (className in _classes)
      return;

    if (className != 'xbObject' && !parentClassName)
      parentClassName = 'xbObject';

    if (!parentClassName)
      parentClassName = null;
    else if !(parentClassName in _classes))
      throw('xbObjects.js:_Classes::registerClass: parentClassName ' + parentClassName + ' not defined');

    // evaluating and caching the prototype object in registerClass
    // works so long as we are dealing with 'normal' source files
    // where functions are created in the global context and then
    // statements executed. when evaling code blocks as in xbCOM,
    // this no longer works and we need to defer the prototype caching
    // to the defineClass method

    _classes[className'classConstructor': null, 'parentClassName': parentClassName };
  }
  _Classes.prototype.registerClass = registerClass;

  function defineClass(className, prototype_func)
  {
    var p;

    if (!className)
      throw('xbObjects.js:_Classes::defineClass: className not given');

    var classRef = _classes[className];
    if (!classRef)
      throw('xbObjects.js:_Classes::defineClass: className ' + className + ' not registered');

    if (classRef.classConstructor)
      return;

    classRef.classConstructor = evalclassName );
    var childPrototype  = classRef.classConstructor.prototype;
    var parentClassName = classRef.parentClassName;

    if (parentClassName)
    {
      var parentClassRef = _classes[parentClassName];
      if (!parentClassRef)
        throw('xbObjects.js:_Classes::defineClass: parentClassName ' + parentClassName + ' not registered');

      if (!parentClassRef.classConstructor)
      {
        // force parent's prototype to be created by creating a dummy instance
        // note constructor must handle 'default' constructor case
        var dummy;
        eval('dummy = new ' + parentClassName + '();');
      }

      var parentPrototype = parentClassRef.classConstructor.prototype;

      for (p in parentPrototype)
      {
        switch (p)
        {
        case 'isa':
        case 'classRef':
        case 'parentPrototype':
        case 'parentConstructor':
        case 'inheritedFrom':
          break;
        default:
          childPrototype[p= parentPrototype[p];
          break;
        }
      }
    }

    prototype_func();

    childPrototype.isa        = className;
    childPrototype.classRef   = classRef;

    // cache method implementor info
    childPrototype.inheritedFrom = new Object();
    if (parentClassName)
    {
      for (p in parentPrototype)
      {
        switch (p)
        {
        case 'isa':
        case 'classRef':
        case 'parentPrototype':
        case 'parentConstructor':
        case 'inheritedFrom':
          break;
        default:
          if (childPrototype[p== parentPrototype[p&& parentPrototype.inheritedFrom[p])
          {
            childPrototype.inheritedFrom[p= parentPrototype.inheritedFrom[p];
          }
          else
          {
            childPrototype.inheritedFrom[p= parentClassName;
          }
          break;
        }
      }
    }
  }
  _Classes.prototype.defineClass = defineClass;
}

// create global instance
var _classes = new _Classes();

// register root class xbObject
_classes.registerClass('xbObject');

function xbObject()
{
  _classes.defineClass('xbObject', _prototype_func);

  this.init();

  function _prototype_func()
  {
    // isa is set by defineClass() to the className
    // Note that this can change dynamically as the class is cast
    // into it's ancestors...
    xbObject.prototype.isa        = null;

    // classref is set by defineClass() to point to the
    // _classes entry for this class. This allows access
    // the original _class's entry no matter how it has
    // been recast.
    // *** This will never change!!!! ***
    xbObject.prototype.classRef      = null;

    xbObject.prototype.inheritedFrom = new Object();

    function init() { }
    xbObject.prototype.init        = init;

    function destroy() {}
    xbObject.prototype.destroy      = destroy;

    function parentMethod(method, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10)
    {
      // find who implemented this method
      var className       = this.isa;
      var parentClassName = _classes[className].classConstructor.prototype.inheritedFrom[method];
      var tempMethod      = _classes[parentClassName].classConstructor.prototype[method];
      // 'cast' this into the implementor of the method
      // so that if parentMethod is called by the parent's method,
      // the search for it's implementor will start there and not
      // cause infinite recursion
      this.isa   = parentClassName;
      var retVal = tempMethod.call(this, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10);
      this.isa   = className;

      return retVal;
    }
    xbObject.prototype.parentMethod    = parentMethod;

    function isInstanceOf(otherClassConstructor)
    {
      var className = this.isa;
      var otherClassName = otherClassConstructor.prototype.isa;

      while (className)
      {
        if (className == otherClassName)
          return true;

        className = _classes[className].parentClassName;
      }

      return false;
    }
    xbObject.prototype.isInstanceOf    = isInstanceOf;
  }
}

// eof: xbObjects.js


</script>
</head>
<body>
<script type="text/javascript">
_classes.registerClass("Shape");

function Shape(iSides) {
    _classes.defineClass("Shape", prototypeFunction);
    this.init(iSides);
    function prototypeFunction() {
        Shape.prototype.init = function(iSides) {
            this.parentMethod("init");
            this.sides = iSides;
        };
        Shape.prototype.getArea = function () {
            return 0;
        };
    }
}

_classes.registerClass("Triangle""Shape");

function Triangle(iBase, iHeight) {
    _classes.defineClass("Triangle", prototypeFunction);
    this.init(iBase,iHeight);
    function prototypeFunction() {
        Triangle.prototype.init = function(iBase, iHeight) {
            this.parentMethod("init"3);
            this.base = iBase;
            this.height = iHeight;
        };
        Triangle.prototype.getArea = function () {
            return 0.5 this.base * this.height;
        };
    }
}

_classes.registerClass("Rectangle""Shape");

function Rectangle(iLength, iWidth) {
    _classes.defineClass("Rectangle", prototypeFunction);
    this.init(iLength, iWidth);
    function prototypeFunction() {
        Rectangle.prototype.init = function(iLength, iWidth) {
            this.parentMethod("init"4);
            this.length = iLength;
            this.width = iWidth;
        }
        Rectangle.prototype.getArea = function () {
            return this.length * this.width;
        };
    }
}

var triangle = new Triangle(1040);
var rectangle = new Rectangle(2050);

alert(triangle.sides);
alert(triangle.getArea());

alert(rectangle.sides);
alert(rectangle.getArea());

</script>

</body>
</html>
25. 9. Inheritance
25. 9. 1. Inheritance
25. 9. 2. Adding new properties and methods to the child class
25. 9. 3. The Call() Method
25. 9. 4. Using 'call method' to call the constructor of base class
25. 9. 5. The Apply() Method
25. 9. 6. Using 'apply method' to call the constructor of the base class
25. 9. 7. Prototype Chaining
25. 9. 8. All new properties and methods of the subclass must come after the assignment of the prototype property
25. 9. 9. Using apply function to call base constructor
25. 9. 10. Using call function to call the constructor from base class
25. 9. 11. Three-level inheritance
25. 9. 12. Using xbObjects to call the function from base class
25. 9. 13. Using xbObjects to build three-level inheritance
25. 9. 14. Hybrid Method for class inheritance
25. 9. 15. Three level inheritance by using the Hybrid Method
25. 9. 16. Class Inheritance
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.