3
class MySystem extends ListIteratingSystem {
    constructor (private creator: EntityCreator) {
        super(MyNode, this.updateNode);
    }

    updateNode() {/* sniiiiip */}

    /* sniiiip */
}

上記のコードでは、updateNode関数をスーパーコールに渡す方法が必要です。コンパイラはこれについて次のように不平を言います。

Keyword 'this' cannot be referenced in initializers in a class body, or in super constructor calls

これを回避する方法について何かアイデアはありますか?ここでのユースケースは、リストトラバーサルなどに関連する多くのボイラープレートコードを、実際の作業を行ういくつかの特定のシステムによって拡張されたこの基本クラスに抽象化したことです。基本クラスには、更新、追加、および削除を呼び出すためのメソッドが必要です...

4

3 に答える 3

5

ユースケースのセマンティクスについては100%明確ではありませんが、目標に応じていくつかのオプションがあります。

updateNodeまず、 //を基本クラスのメンバーとして定義しaddNoderemoveNode派生クラスに(コンストラクター引数として指定するのではなく)それらをオーバーライドさせることです。TypeScriptには「abstract」の概念がないため、これは派生実装では少しわかりにくくなりますが、おそらく最もクリーンで簡単です。

2つ目は、少しリファクタリングして、派生クラスにメソッドのリストではなく引数を提供させ、更新/追加/削除関数を「姉妹」クラスに配置して、基本クラスが提供できるようにその機能を提供することです。それらは、そうでなければ取得する必要のあるコンテキストですthis。これはより多くの作業ですが、関心の分離がはるかに優れています。制御パターンの反転を実行しようとしている場合は、継承よりも合成によって実行する方がおそらく適切です。

最後のオプションは、ここでクラス階層全体を上下逆にして、トラバーサル/ etcコードをこれらの個々の実装が使用する別のクラスに移動し、基本的に既存のコードの制御の反転を逆反転することです。

基本クラスのコンストラクターの引数の位置で参照しない制限thisは、一般的に非常に優れていることを付け加えておきます。これに違反しようとすると、通常、さらに先の失敗に備えることになります。この場合、制限が設定されていないと、から継承しようとしたMySystemとき、または構築中にいつかListIteratingSystem呼び出す必要があると判断したときに、大きな問題が発生する可能性があります。updateNodeC#のFxCopは、これと同じ理由でこの制限を適用します。

于 2012-11-30T06:56:19.877 に答える
3

次のようなメソッドをオーバーライドしないのはなぜですか。

class ListIteratingSystem {
    execute() {
        this.executeOnStart();
    };

    private executeOnStart() {
       throw new Error('This method is abstract');
    };
};

class MySystem extends ListIteratingSystem {
    constructor (/*...*/) {
        super();
    }

   private executeOnStart() {
       alert("derived");
    };
}

new MySystem().execute();ディスプレイアラートの実行。

残念ながら、メソッドを作成するための優れたexecuteOnStart方法はprotected abstractまだありません。これは少し直感に反しますが、可視性アクセサーはコンパイラーとインテリジェンス専用であることを忘れないでください。

于 2012-11-30T06:52:26.320 に答える
3

TypeScript 1.3では、保護されたキーワードと遅延バインディングを使用できるため、メソッドをスーパークラスに渡す必要はありません。

キーワードはまだないabstractので、デフォルトの動作を指定するか、基本クラスで例外をスローする必要がありますが、protectedキーワードを使用すると、基本クラスの実装をオーバーライドできます(privateキーワードでは、現在のバージョンのTypeScriptではこれを許可しません) 。

class ListIteratingSystem {
    doSomething() {
        this.updateNode();
    }

    protected updateNode() {
        alert('Super');
    }
}

class MySystem extends ListIteratingSystem {
    protected updateNode() {
        alert('Sub');
    }
}

var a = new ListIteratingSystem();
a.doSomething();

var b = new MySystem();
b.doSomething();
于 2014-11-17T08:05:46.847 に答える