0

TypeScript には、「抽象」クラス自体はありません。しかし、構造型付けのため、インターフェースはやや弱いです。x instanceof Yたとえば、Yがインターフェイスであると断言することはできません。

ただし、コンストラクターで初期化されていないクラス フィールドは、すでに抽象プロパティのように動作していることに気付きました。クラスのに表示されますが、実際に割り当てられない限り実行時に存在しません。Yクラスが以下の例を行うように、これにより、基本クラスのフィールドの定義をサブクラスのプロパティ定義によって「オーバーライド」できます。

class X {
   // behaves somewhat like an abstract property
   i: number
}

class Y extends X {
   _i: number

   constructor () {
      super()
      this._i = 7
   }

   // Provide an "implementation" of i
   get i (): number {
      return this._i
   }

   set i (i: number) {
      this._i = i
   } 
}

一方、Z以下では、継承されたフィールドを使用して、割り当てます。

// This sub-class uses the inherited field.
class Z extends X {
   constructor () {
      super()
      this.i = 6
   }
}

Xを介してフィールドを使用しようとするとnew X、フィールドは未定義です。の場合Y、オーバーライド プロパティが選択されます。の場合Z、継承された定義が使用されます。

function testProp (): void {
   var x: X
   x = new X
   console.log(x.i) // undefined
   x = new Y
   console.log(x.i) // 7
   x = new Z
   console.log(x.i) // 6
}

これは TypeScript の「抽象プロパティ」への合理的なアプローチですか? のようなことを主張できるようにしたいのですがx instanceof X(これは のインターフェイスを使用することを妨げますX)、このイディオムは今のところうまくいっているようです。

4

1 に答える 1

1

ソリューションが機能しなくなるのは、プロパティへの割り当てを開始できることに気付いたときです...

var x: X = new X();
x.i = 5;
console.log(x.i);

これはもはや抽象的ではありません。

これを防ぐには、次のようなコードの使用を開始できます...

class Foo {
    get x(): number {
        return undefined;
    }

    set x(val: number) {
        // nothing
    }
}

ただし、多数のプロパティに対してこれを行うと、基本クラスが膨張し始める可能性があります。

于 2013-11-13T16:50:02.040 に答える