define subclass - js
------
define subclass
definition of subclass:
assume there are function A and B, if A.prototype.prototype = B.prototype, then A is subclass of B,
to complete the subclass, there are more things to do than extends prototype, see following steps,
steps to create subclass:
* B.prototype extends from A.prototype
* B.prototype.constructor = B
* in B's constructor body
* use apply()/call() to invoke B's constructor with arguments,
* define new things for B,
* override A's method/property, if necessary,
* define things on new constructor
------
how create a prototype extends from another prototype
how to create sub prototype:
create a new function whose prototype is the super prototype, then the new function could be used as the sub prototype,
how to do:
* in ECMAScript5:
use Object.create(p),
* in ECMAScript3:
create an function, point its prototype to ther super prototype,
util function to create a sub prototype:
/**
* create a sub prototype which extends from specified super prototype
*
* @param: p
super prototype
* @return
sub prototype
*/
function inherit(p) {
if (p == null) throw TypeError(); // p must be a non-null object
if (Object.create) // If Object.create() is defined...
return Object.create(p); // then just use it.
var t = typeof p; // Otherwise do some more type checking
if (t !== "object" && t !== "function") throw TypeError();
function f() {}; // Define a dummy constructor function.
f.prototype = p; // Set its prototype property to p.
return new f(); // Use f() to create an "heir" of p.
}
------
abstract class / interface
abstract class & interface:
are class that include abstract method, in js abstract method could be a method that throw an exception,
implementation:
in the subclass, override the abstract method, thus get a class without abstract method,
------
e.g.
include:
* inherit_util.js
include some util methods for inherit,
* subclass_example_1.js
a example use inherit()/extend() directly,
* subclass_example_2.js
a example use defineSubclass(),
* subclass_example_3.js
a example use Function.prototype.extend(),
inherit_util.js:
/**
* util function copy enumerable property of p to object o
*
* @param o
* @param p
* @returns
*/
function extend(o, p) {
for (prop in p) { // For all props in p.
o[prop] = p[prop]; // Add the property to o.
}
return o;
}
/**
* create a prototype which inherit from specified prototype
*
* @param p
* super prototype
* @returns sub prototype
*/
function inherit(p) {
if (p == null)
throw TypeError(); // p must be a non-null object
if (Object.create) // If Object.create() is defined...
return Object.create(p); // then just use it.
var t = typeof p; // Otherwise do some more type checking
if (t !== "object" && t !== "function")
throw TypeError();
// Define a dummy constructor function.
function f() {
}
f.prototype = p; // Set its prototype property to p.
return new f(); // Use f() to create an "heir" of p.
}
/**
* util function to define subclass, extends from specified superclass, and add
* new methods/properties to prototype/constructor, this function depends on
* extend() & inherit(),
*
* @param superclass
* Constructor of the superclass
* @param constructor
* The constructor for the new subclass
* @param methods
* Instance methods to copied to prototype, the param should be an
* object contain methods/properties
* @param statics
* Class properties to copied to constructor, the param should be a
* object contain methods/properties,
* @return the new constructor
*/
function defineSubclass(superclass, constructor, methods, statics) {
// inherit from super prototype
constructor.prototype = inherit(superclass.prototype);
// set the constructor property of the new prototype
constructor.prototype.constructor = constructor;
// copy instance properties/methods to copied to prototype
if (methods)
extend(constructor.prototype, methods);
// copy class properties/methods to constructor
if (statics)
extend(constructor, statics);
// Return the class
return constructor;
}
/**
* add the extend method to js Function, so that apply to all function of js,
*
* @param constructor
* @param methods
* @param statics
* @returns the new constructor
*/
Function.prototype.extend = function(constructor, methods, statics) {
return defineSubclass(this, constructor, methods, statics);
};
/**
* an abstract method, which throws error
*/
function abstractMethod() {
throw new Error("method not implemented");
}
subclass_example_1.js:
// depends on inherit_util.js
// super class
function A() {
this.pone = "A-pone";
this.ptwo = "A-ptwo";
}
A.prototype.mone = function() {
console.log("A-mone");
};
// super class has a abstract method
A.prototype.mtwo = abstractMethod;
A.prototype.mthree = function() {
console.log("A-mthree");
};
// sub class
function B() {
// invoke super constructor on sub object, so that to extends things defined
// in super constructor,
A.apply(this);
// override super property from super constructor,
this.pone = "B-pone";
}
// extends from super prototype
B.prototype = inherit(A.prototype);
// set the constructor property of sub prototype, after extends prototype,
B.prototype.constructor = B;
// implemet(override) abstract method of super class
B.prototype.mtwo = function() {
console.log("B-mtwo");
};
// override method of super class
B.prototype.mthree = function() {
console.log("B-mthree");
};
function test() {
var b = new B();
b.mone();
b.mtwo();
b.mthree();
console.log(b.pone);
console.log(b.ptwo);
}
test();
subclass_example_2.js:
// depends on inherit_util.js
// super class
function A() {
this.pone = "A-pone";
this.ptwo = "A-ptwo";
}
A.prototype.mone = function() {
console.log("A-mone");
};
// super class has a abstract method
A.prototype.mtwo = abstractMethod;
A.prototype.mthree = function() {
console.log("A-mthree");
};
// sub class
function B() {
// invoke super constructor on sub object, so that to extends things defined
// in super constructor,
A.apply(this);
// override super property from super constructor,
this.pone = "B-pone";
}
// extends from super prototype
defineSubclass(A, B, {
mtwo : function() {
console.log("B-mtwo");
},
mfour : function() {
console.log("B-mfour");
}
}, {
sfone : "staticFieldOne"
});
function test() {
var b = new B();
b.mone();
b.mtwo();
b.mthree();
b.mfour();
console.log(b.pone);
console.log(b.ptwo);
console.log(b.constructor.sfone);
}
test();
subclass_example_3.js:
// depends on inherit_util.js
// super class
function A() {
this.pone = "A-pone";
this.ptwo = "A-ptwo";
}
A.prototype.mone = function() {
console.log("A-mone");
};
// super class has a abstract method
A.prototype.mtwo = abstractMethod;
A.prototype.mthree = function() {
console.log("A-mthree");
};
// sub class
function B() {
// invoke super constructor on sub object, so that to extends things defined
// in super constructor,
A.apply(this);
// override super property from super constructor,
this.pone = "B-pone";
}
// extends from super class
A.extend(B, {
mtwo : function() {
console.log("B-mtwo");
},
mfour : function() {
console.log("B-mfour");
}
}, {
sfone : "staticFieldOne"
});
function test() {
var b = new B();
b.mone();
b.mtwo();
b.mthree();
b.mfour();
console.log(b.pone);
console.log(b.ptwo);
console.log(b.constructor.sfone);
}
test();
------
本文详细介绍了JavaScript中类的继承机制,包括如何创建子类、子类如何从父类继承属性和方法,以及如何使用不同的方法创建子类原型。通过多个示例,展示了如何在实际代码中应用这些概念。

1158

被折叠的 条评论
为什么被折叠?



