インターフェースと基本クラスの組み合わせを使用するとうまくいくと思います。コンパイル時に動作要件を適用します(rq_ post "below"は上の投稿を指しますが、これはこれではありません)。
インターフェースは、基本クラスが満たしていない動作APIを設定します。インターフェイスで定義されたメソッドを呼び出すように基本クラスメソッドを設定することはできません(これらの動作を定義する必要がないため、基本クラスでそのインターフェイスを実装することができないため)。たぶん、誰かが親のインターフェースメソッドの呼び出しを許可するための安全なトリックを考え出すことができます。
インスタンス化するクラスで拡張および実装することを忘れないでください。ランタイム失敗コードの定義に関する懸念を満たします。また、インターフェイスを実装していない場合(Animalクラスをインスタンス化しようとした場合など)は、起動するメソッドを呼び出すこともできません。インターフェースで以下のBaseAnimalを拡張してみましたが、BaseAnimalのコンストラクターと 'name'フィールドがSnakeから隠されていました。もしそれができたなら、モジュールとエクスポートを使用することで、BaseAnimalクラスの偶発的な直接インスタンス化を防ぐことができたでしょう。
これをここに貼り付けて、機能するかどうかを確認します。http://www.typescriptlang.org/Playground/
// The behavioral interface also needs to extend base for substitutability
interface AbstractAnimal extends BaseAnimal {
// encapsulates animal behaviors that must be implemented
makeSound(input : string): string;
}
class BaseAnimal {
constructor(public name) { }
move(meters) {
alert(this.name + " moved " + meters + "m.");
}
}
// If concrete class doesn't extend both, it cannot use super methods.
class Snake extends BaseAnimal implements AbstractAnimal {
constructor(name) { super(name); }
makeSound(input : string): string {
var utterance = "sssss"+input;
alert(utterance);
return utterance;
}
move() {
alert("Slithering...");
super.move(5);
}
}
var longMover = new Snake("windy man");
longMover.makeSound("...am I nothing?");
longMover.move();
var fulture = new BaseAnimal("bob fossil");
// compile error on makeSound() because it is not defined.
// fulture.makeSound("you know, like a...")
fulture.move(1);
以下にリンクされているように、FristvanCampenの答えに出くわしました。彼は、抽象クラスはアンチパターンであり、実装クラスの注入されたインスタンスを使用して、ベースの「抽象」クラスをインスタンス化することを提案しています。これは公平ですが、反対意見が出されています。ご自身でお読みください:https :
//typescript.codeplex.com/discussions/449920
パート2:抽象クラスが必要な別のケースがありましたが、「抽象クラス」で定義されたメソッドは、一致するインターフェースで定義されたメソッドを参照する必要があるため、上記のソリューションを使用できませんでした。それで、私はFristvanCampenのアドバイスを整理します。メソッドの実装を含む不完全な「抽象」クラスがあります。実装されていないメソッドとのインターフェースがあります。このインターフェースは「抽象」クラスを拡張します。次に、最初のクラスを拡張して2番目のクラスを実装するクラスがあります(それ以外の場合は、スーパーコンストラクターにアクセスできないため、両方を拡張する必要があります)。以下の(実行不可能な)サンプルを参照してください。
export class OntologyConceptFilter extends FilterWidget.FilterWidget<ConceptGraph.Node, ConceptGraph.Link> implements FilterWidget.IFilterWidget<ConceptGraph.Node, ConceptGraph.Link> {
subMenuTitle = "Ontologies Rendered"; // overload or overshadow?
constructor(
public conceptGraph: ConceptGraph.ConceptGraph,
graphView: PathToRoot.ConceptPathsToRoot,
implementation: FilterWidget.IFilterWidget<ConceptGraph.Node, ConceptGraph.Link>
){
super(graphView);
this.implementation = this;
}
}
そして
export class FilterWidget<N extends GraphView.BaseNode, L extends GraphView.BaseLink<GraphView.BaseNode>> {
public implementation: IFilterWidget<N, L>
filterContainer: JQuery;
public subMenuTitle : string; // Given value in children
constructor(
public graphView: GraphView.GraphView<N, L>
){
}
doStuff(node: N){
this.implementation.generateStuff(thing);
}
}
export interface IFilterWidget<N extends GraphView.BaseNode, L extends GraphView.BaseLink<GraphView.BaseNode>> extends FilterWidget<N, L> {
generateStuff(node: N): string;
}