4

クラス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は何か違いがありますか?

4

3 に答える 3

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`

実際には、Javaで知っているようにmynamespace.A、抽象メソッドを使用して抽象クラスをエミュレートできると思います。myMethodBサブクラス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
    }

});
于 2012-05-18T21:17:35.980 に答える
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の両方に対してプロトタイプ化されるオーバーライドに遭遇した場合、宣言/構築チェーンには、「スーパー」(または表記に従って親クラス)を呼び出すことができるメカニズムがあります。

特別なプロパティコンストラクターの場合、継承がバブル[期間]になるように常にそうです。

一度だけ宣言されたメソッドの場合、継承されたメソッドでない場合は、自分自身で呼び出すことはできません。その後、「this」を介してアクセスできます。

オーバーライドがあるメソッドの場合、関数'this.inherited(arguments);' 呼び出し先の現在の親クラスに1ティック上向きに送信します。ここで拡張フィドルを見てください

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();
于 2012-05-19T11:08:58.570 に答える
0

プロトタイプオブジェクトを使用して、任意のメソッドを呼び出すことができます。

myMethodA: function() { mynamespace.B.prototype.myMethodB(); }

実例は次のとおりです。

http://jsfiddle.net/cswing/7cBJm/

于 2012-05-18T20:46:34.133 に答える