인터페이스와 기본 클래스의 조합을 사용하면 효과가 있다고 생각합니다. 컴파일 타임에 행동 요구 사항을 시행합니다 (rq_ post "아래"는 위의 게시물을 의미합니다).
인터페이스는 기본 클래스가 충족하지 않는 동작 API를 설정합니다. 인터페이스에 정의 된 메소드를 호출하도록 기본 클래스 메소드를 설정할 수 없습니다 (이러한 동작을 정의하지 않고 기본 클래스에서 해당 인터페이스를 구현할 수 없기 때문에). 어쩌면 누군가 부모의 인터페이스 메소드 호출을 허용 하는 안전한 트릭을 만들 수 있습니다.
인스턴스화 할 클래스에서 확장하고 구현해야합니다. 런타임 실패 코드 정의에 대한 우려를 만족시킵니다. 또한 인터페이스를 구현하지 않은 경우 (예 : Animal 클래스를 인스턴스화하려는 경우) 발생하는 메소드를 호출 할 수도 없습니다. 인터페이스를 아래 BaseAnimal로 확장하려고 시도했지만 Snake에서 BaseAnimal의 생성자 및 'name'필드를 숨겼습니다. 내가 그렇게 할 수 있다면, 모듈과 내보내기를 사용하면 우연히 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의 조언을 도구로 사용합니다. 메소드 구현과 함께 불완전한 "추상"클래스가 있습니다. 구현되지 않은 메소드와의 인터페이스가 있습니다. 이 인터페이스는 "추상"클래스를 확장합니다. 그런 다음 첫 번째를 확장하고 두 번째를 구현하는 클래스가 있습니다 (그렇지 않으면 수퍼 생성자가 액세스 할 수 없으므로 둘 다 확장해야합니다). 아래의 (실행 불가능한) 샘플을 참조하십시오.
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;
}