JS中的多态和深度继承
我正在使用 JS Gavin Kistner 的原型继承模式,但我不太确定为什么深度继承对我不起作用。
我希望 C 继承自 B 继承自 A...
Function.prototype.inheritsFrom = function( parentClassOrObject )
{
if ( parentClassOrObject.constructor == Function )
{
//Normal Inheritance
this.prototype = new parentClassOrObject;
this.prototype.constructor = this;
this.prototype.parent = parentClassOrObject.prototype;
}
else
{
//Pure Virtual Inheritance
this.prototype = parentClassOrObject;
this.prototype.constructor = this;
this.prototype.parent = parentClassOrObject;
}
return this;
}
function A() {
// ...
}
A.prototype.init = function( arg ) {
// ...
}
function B() {
A.apply( this, arguments ); // call super constructor
// ...
}
B.inheritsFrom( A );
B.prototype.init = function( arg ) {
B.parent.init.call( this, arg );
// ...
}
function C() {
B.apply( this, arguments ); // call super constructor
// ...
}
C.inheritsFrom( B );
C.prototype.init = function( arg ) {
this.parent.init.call( this, arg );
// ...
}
var foo = new C();
foo.init( 10 );
// Throws an exception: infinite call loop.
当我调用 foo.init()
时,我实际上是在调用 C.init()
在 C.init()
内“this”是 C 类型
-> this.parent.init.call( this, arg )
实际上是在调用 B.init()
在 B.init()
内部,'this' 仍然是 C 类型(因为 .call(this)
)
-> this.parent.init.call( this, arg )
再次调用 B.init()
因此它会进入 B 上的无限调用循环.init()
...
我做错了什么?
我应该简单地将 B 和 C 的 'init' 重命名为其他名称吗?我宁愿不这样做,因为当前的方式允许我调用 obj.init() ,无论 obj 是 A、B 还是 C 类型...
I'm using the JS prototype inheritance pattern from Gavin Kistner and I'm not quite sure why deep inheritance doesn't work for me.
I want C inherits from B inherits from A...
Function.prototype.inheritsFrom = function( parentClassOrObject )
{
if ( parentClassOrObject.constructor == Function )
{
//Normal Inheritance
this.prototype = new parentClassOrObject;
this.prototype.constructor = this;
this.prototype.parent = parentClassOrObject.prototype;
}
else
{
//Pure Virtual Inheritance
this.prototype = parentClassOrObject;
this.prototype.constructor = this;
this.prototype.parent = parentClassOrObject;
}
return this;
}
function A() {
// ...
}
A.prototype.init = function( arg ) {
// ...
}
function B() {
A.apply( this, arguments ); // call super constructor
// ...
}
B.inheritsFrom( A );
B.prototype.init = function( arg ) {
B.parent.init.call( this, arg );
// ...
}
function C() {
B.apply( this, arguments ); // call super constructor
// ...
}
C.inheritsFrom( B );
C.prototype.init = function( arg ) {
this.parent.init.call( this, arg );
// ...
}
var foo = new C();
foo.init( 10 );
// Throws an exception: infinite call loop.
When I call foo.init()
, I'm actually calling C.init()
Inside C.init()
'this' is of type C
-> this.parent.init.call( this, arg )
is actually calling B.init()
Inside B.init()
'this' is still of type C ( because of .call(this)
)
-> this.parent.init.call( this, arg )
is, again, calling B.init()
And therefore it goes into an infinite call loop on B.init()
...
What am I doing wrong ?
Should I simply rename 'init' to something else for B and C ? I would rather not, because the current way allows me to call obj.init()
whether obj is of type A, B or C...
将
B.parent.init.call( this, arg );
更改为B.prototype.parent.init.call( this, arg );
。Change
B.parent.init.call( this, arg );
toB.prototype.parent.init.call( this, arg );
.