bry*_*ing 6 oop design-patterns typescript
我试图通过在TypeScript中编写代码来跟随C#设计模式书.也许这是我的第一个错误,但这是我喜欢学习语言的一种方式.
TypeScript不支持类的抽象关键字,所以我试图模拟它.也许这是我的第二个错误.
这是我的界面和类:
interface IEngine {
getSize(): number;
getTurbo(): boolean;
}
class AbstractEngine implements IEngine {
constructor(private size: number, private turbo: boolean) {
throw "Abstract class";
}
public getSize(): number {
return this.size;
}
public getTurbo(): boolean {
return this.turbo;
}
public toString(): string {
var funcNameRegex = /function (.{1,})\(/;
var results = (funcNameRegex).exec(this.constructor.toString());
var className = (results && results.length > 1) ? results[1] : '';
return className + " (" + this.size + ")";
}
}
class StandardEngine extends AbstractEngine {
constructor(size: number) {
// not turbo charged
super(size, false);
}
}
Run Code Online (Sandbox Code Playgroud)
当我尝试实例化AbstractEngine时,new AbstractEngine(1, true)
我得到了一个"抽象类"错误.
当我尝试用new StandardEngine(9000)
我实例化StandardEngine时,我也得到一个"抽象类"错误.
有没有办法可以在TypeScript中模拟一个抽象类,让它无法实例化,但仍然可以在扩展它的类中调用super?那么模拟抽象方法呢,我可以保护那些仍然可以调用超级方法吗?
截至今天,TypeScript 1.6已经上线,并且支持该abstract
关键字.
abstract class A {
foo(): number { return this.bar(); }
abstract bar(): number;
}
var a = new A(); // error, Cannot create an instance of the abstract class 'A'
class B extends A {
bar() { return 1; }
}
var b = new b(); // success, all abstracts are defined
Run Code Online (Sandbox Code Playgroud)
我建议你不要这样做。当 TypeScript 编译器实现抽象函数的机制时,就该使用它了。但在运行时起作用的 hack 是难以理解的,并且会降低性能。
\n\n界面是 TypeScript 的强大优势。它们应该被大量使用。
\n\n你的例子应该这样写:
\n\ninterface Engine {\n getSize(): number;\n getTurbo(): boolean;\n}\n\nclass StandardEngine implements Engine {\n constructor(private size: number, private turbo: boolean) {\n }\n public getSize(): number {\n return this.size;\n }\n public getTurbo(): boolean {\n return this.turbo;\n }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n最简单的解决方案往往是最好的。
\n\n如果您想在没有父类的情况下重用代码,那么该代码必然可用,手册建议使用 Mixins。Mixin 是一种应对来自多个不同实体的技能的方法。
\n\n或者使用模块,可以保留私有实现(因此可以根据需要组织它)并仅导出接口和工厂。一个例子:
\n\nmodule MyEngineModule {\n export interface Engine {\n getSize(): number;\n getTurbo(): boolean;\n }\n export interface StandardEngine extends Engine {\n }\n export function makeStandardEngine(size: number, turbo: boolean): StandardEngine {\n return new ImplStandardEngine(size, turbo);\n }\n // here classes are private and can inherit or use mixins\xe2\x80\xa6\n class ImplEngine {\n constructor(private size: number, private turbo: boolean) {\n }\n public getSize(): number {\n return this.size;\n }\n public getTurbo(): boolean {\n return this.turbo;\n }\n }\n class ImplStandardEngine extends ImplEngine implements StandardEngine {\n }\n}\nconsole.log(MyEngineModule.makeStandardEngine(123, true).getSize());\n
Run Code Online (Sandbox Code Playgroud)\n
归档时间: |
|
查看次数: |
3462 次 |
最近记录: |