typescript - TypeScript :: 继承问题
问题描述
我有一个实现一堆方法的基类,每个方法都返回一个对对象副本的新引用以允许链接。
class Base {
constructor(public name: string) {}
funcA(): Base { return new Base('FUNC_A') }
funcB(): Base { return new Base('FUNC_B') }
}
另外,我有一个派生类,只暴露了基类的一些方法,也暴露了它自己的方法。所有这些方法都应该返回对派生类对象的引用以允许链接。
class Derived extends Base {
constructor() { super('DERIVED') }
funcA(): Derived { return super.funcA() }
newFunc(): Derived { return new Derived() }
}
在这种情况下,我遇到了问题。被覆盖的方法返回的对象仍然是基类的一个实例,不管它是否被强制转换为派生类,派生类中第一次定义的方法都没有被定义。
我想到了一种解决方法,它并不优雅。代替继承,我可以使用组合在派生类对象中包含基类对象的实例。但是,为此,我需要一个额外的构造函数来接受一个基类对象,该对象应该可以在类外部访问,并像funcA(): Derived { return new Derived(this.baseObject) }
.
有没有更优雅的方法来解决这个问题?
解决方案
我认为这符合您的预期:
class Base {
constructor(public name: string) {}
funcA(): this { return new (this.constructor as any)('FUNC_A') }
funcB(): this { return new (this.constructor as any)('FUNC_B') }
}
class Derived extends Base {
constructor() { super('DERIVED') }
funcA(): this { return super.funcA() }
newFunc(): this { return new (this.constructor as any)() }
}
解释:
使用funcA(): this
而不是funcA(): Base
告诉 TypeScript,该函数返回一个与调用它的类相同类型的对象,而不是总是Base
. 如果调用它的实例Base
应该返回一个实例,Base
如果调用Derived
它应该返回一个实例Derived
。
要正确实现这一点,调用new Base()
将是错误的,因为它总是返回 base 的实例。要访问实际实例的构造函数,每个 javascript 对象都有一个this.constructor
属性(参见:https ://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor )。所以我打电话new this.constructor()
而不是new Base()
. 如果在的实例上调用并且如果在的实例上调用将this.constructor
是Base
Base
Derived
Derived
遗憾的是 typescript 没有识别this.constructor
为正确的类型,这将是类型的构造函数new (...any[]) => this
(参见https://github.com/microsoft/TypeScript/issues/3841)所以我只是将它转换为any
. 也许有更好的方法来做到这一点,我不知道。
如果你必须更频繁地调用构造函数,你可以为它创建一个方法,这样你就可以更容易地编写它:
class Base {
constructor(public name: string) {}
newInstance(...args: any[]): this { return new (this.constructor as any)(...args); }
funcA(): this { return this.newInstance('FUNC_A') }
funcB(): this { return this.newInstance('FUNC_B') }
}
class Derived extends Base {
constructor() { super('DERIVED') }
funcA(): this { return super.funcA() }
newFunc(): this { return this.newInstance() }
}
推荐阅读
- database - 在颤动中传递数据
- python - Python - SQL 查询不会返回字符“Æ”、“Ø”和“Å”
- javascript - 尽管路径正确,但在 Asp.NET 中找不到资源?
- angular - 使用参数定义路由时出现角度路由问题
- doxygen - 另一个 doxygen 什么都不产生
- mysql - 我检查了每一条信息,但我仍然没有找到我的目标。我一直在努力提高,但在这种情况下我根本做不到
- oracle - 将值添加到服务器启动参数 oracle weblogic
- google-app-engine - 将 AppEngine 中的传入请求路由到不同版本
- python - 如何使用 GIT 配置 RFlinter 以在每次提交时自动对机器人文件运行 linter 检查
- sql - EF Core 3.1 - 数据库优先和继承