给定A类和B类,其中B类继承自A类......
// Define class A
dojo.declare("mynamespace.A",null,{
myMethodA: function() { this.myMethodB() }
});
// Define class B
dojo.declare("mynamespace.B",mynamespace.A,{
myMethodB: function() {}
});
在A类(父类)的范围内调用this.myMethodB()是否合法? 我在一个软件中看到过这个,我不明白。我知道在Java中,除非你将A类型转换为B,否则这是不可能的。但dojo有什么不同吗?
答案 0 :(得分:1)
JavaScript中没有静态编译,因此,正如@akonsu所提到的那样,技术上可行,但这不是一种模式:
var a = new mynamespace.A();
a.myMethodA(); // ilegal: Uncaught TypeError: Object [object Object] has no method 'methodB'
var b = new mynamespace.B();
b.myMethodA() // legal
您还可以在JavaScript中的给定范围内执行方法/函数,即作为给定对象的方法:
a.myMethodA.call(b); // legal as `this` inside `myMethodA` will be referencing to object `b`
实际上,我认为mynamespace.A
可以使用抽象方法myMethodB
模拟抽象类,正如您从Java中所知道的那样。类mynamespace.A
当子类化时,子类应该实现myMethodB
。但是这样做非常容易出错,我会以更强大的方式做到这一点:
// Define class A
dojo.declare("mynamespaca.A", null, {
myMethodA: function() {
this.myMethodB();
},
myMethodB: function() {
// abstract method
console.warn("Abstract method [myMethodB] was not implemented.");
// or: throw new Error("Abstract method [myMethodB] was not implemented.");
}
});
// Define class B
dojo.declare("mynamespace.B", mynamespace.A, {
myMethodB: function() {
// implement abstract method here
}
});
答案 1 :(得分:1)
这个问题的流行语将是 this.inherited(arguments); 你的问题是调用一个不在当前继承范围内的方法 - 并且真正的面向对象的程序员会被称为无效。然而,由于加载器在全局范围内声明了所有内容,因此可能(仍然)。您可以通过 mynamespace.X访问任何模块,然后添加prototype.theMethod。
在mynamespace.B中继承之后,A和B的所有功能都是'this'范围。它就像是一个合并的哈希,比如for all methods and variables in A do set instance B[key] = property A[key]
。
但是如果你遇到一个覆盖,其中属性是'A'和B类的原型 - 在declare / construct链中有一个机制允许调用'super'(或父类,遵循你的符号)
对于特殊属性构造函数,它总是这样,继承起泡[句号]。
对于任何只声明一次的方法,如果它不是一个继承的方法,你就不能自称它 - 然后它就可以通过'this'访问了
对于任何具有覆盖的方法,函数'this.inherited(arguments);'将向上发送,一个勾选到当前被调用者的父类。看看扩展小提琴here
var AClass = dojo.declare("mynamespace.A", null, {
constructor: function(args) {
this.overriddenMethod();
},
overriddenMethod: function() {
}
});
var BClass = dojo.declare("mynamespace.B", [AClass], {
constructor: function() { },
overriddenMethod: function() {
// call super before anything else is processed in this method
// by placing following call you can control function callflow
this.inherited(arguments);
}
});
// will call A.constructor, then A.overriddenMethod
new AClass();
// will call B.constructor, A.constructor, B.overriddenMethod and then
// A.overriddenMethod via the call to super
// in B.overriddenMethod which A.constructor
// calls (note that A.constructor callflow 'aims' B.override not A.override)
new BClass();
答案 2 :(得分:0)
您可以使用原型对象调用任何方法。
myMethodA: function() { mynamespace.B.prototype.myMethodB(); }
这是一个有效的例子: