Roy*_*son 7 abstract-class class factory-method abstract typescript
前言 - 我在 SO 上看过与此类似的帖子,但答案似乎不适用。
我有一个具有以下方法的抽象类(简化):
playAnimation() {
let animator = this.createAnimator(this.animatorData)
await animator.animate()
}
Run Code Online (Sandbox Code Playgroud)
Create animator 在该抽象类中有以下定义:
abstract createAnimator(animatorData: Object): Animator
Run Code Online (Sandbox Code Playgroud)
子类可能会createAnimator
这样实现:
createAnimator(animatorData: StandardAnimatorData) {
return new RiverAnimator(animatorData.addMessage, animatorData.assetsDir)
}
Run Code Online (Sandbox Code Playgroud)
或者像这样:
createAnimator(animatorData: StandardAnimatorData) {
return new BridgeAnimator(animatorData.addMessage, animatorData.assetsDir)
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的 - 两个子类的实现createAnimator
大致相同,除了返回的类型之外Animator
。
SidenoteBridgeAnimator
和RiverAnimator
两者都实现了Animator
接口,但如果解决方案需要Animator
是一个抽象类,我可以更改它。
有没有办法进入createAnimator
抽象基类?
理想情况下,抽象类应该有一个抽象变量,它是应该返回的类的类型createAnimator
。子类只会实现该变量。然后createAnimator
使用该变量返回正确的类型Animator
。
是的,你可以做这样的事情(我制作了一个大的代码片段,这样我就可以验证所有内容是否都可以编译):
interface Animator {
animate(): Promise<void>;
}
class RiverAnimator implements Animator {
async animate() { }
constructor(addMessage: unknown, assetsDir: unknown) { }
}
class BridgeAnimator implements Animator {
async animate() { }
constructor(addMessage: unknown, assetsDir: unknown) { }
}
interface StandardAnimatorData {
addMessage: unknown;
assetsDir: unknown;
}
// Common interface for the constructor functions RiverAnimator and BridgeAnimator
interface AnimatorConstructor {
new(addMessage: unknown, assetsDir: unknown): Animator;
}
abstract class AbstractOuterClass {
abstract animatorConstructor: AnimatorConstructor;
animatorData: StandardAnimatorData;
createAnimator(data: StandardAnimatorData) {
return new this.animatorConstructor(data.addMessage, data.assetsDir);
}
async playAnimation() {
let animator = this.createAnimator(this.animatorData);
await animator.animate();
}
}
class SubOuterClass1 extends AbstractOuterClass {
animatorConstructor = RiverAnimator;
}
class SubOuterClass2 extends AbstractOuterClass {
animatorConstructor = BridgeAnimator;
}
Run Code Online (Sandbox Code Playgroud)
但我不清楚这是否比createAnimator
在SubOuterClass1
和中实现更好SubOuterClass2
。
另一种方法是利用泛型的力量:
宣言:
createAnimator<T extends Animator>(
type: { new(addMessage: unknown, assetDir: unknown): T },
animatorData: StandardAnimatorData
): T {
return new type(animatorData.addMessage, animatorData.assetDir);
}
Run Code Online (Sandbox Code Playgroud)
调用:
let animator = this.createAnimator(BridgeAnimator, animatorData);
await animator.animate();
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
11383 次 |
最近记录: |