我使用了一个要在Typescript中扩展的库。这个库有一个我扩展的类:
import lib from 'lib'
class MyClass extends lib.ItsClass {
}
该库还有一个函数,该函数返回其类的一个实例。我想从那个实例创建一个类的实例。
const its_instance:lib.ItsClass = lib.returnInstance();
const myclass:MyClass = ...
如何在MyClass
的实例中转换its_instance
?
听起来基类正在使用Singleton模式。这是一种确保类只有一个实例的方法。
以下是通常情况下的基本总结。构造函数被设置为private
,因此不能通过调用new
来创建实例,除非在类中。类的唯一实例存储到名称类似instance
的private static
属性中。当您调用public static method returnInstance()
时,它会检查是否已设置instance
属性。如果没有,它会调用new
来创建实例,然后在返回之前将其保存到变量中
单身汉并不是真的被设计成可以扩展的。这个类很可能使用private
方法和属性,尽管在Javascript中private
更多的是一个建议而非规则。
另一个问题是,应该只有一个实例,但现在有两个版本并不完全兼容。如果基方法首先调用returnInstance()
并将实例设置为基类,那么这会给扩展类带来问题。
解决这一问题的一种方法是将扩展类的实例存储在不同的属性名称下,并具有两个独立的实例,但现在您的实例和基实例彼此分离,并具有独立的状态。
最终,最干净的方法是包装类,而不是扩展它。类在内部存储对基类实例的引用(或者每次只调用LibClass.getInstance(((。它模仿基类的方法,但将实际执行委派给基实例。
因为typescript类也是接口,所以我们可以说MyClass implements LibClass
。这意味着MyClass
应该能够在LibClass
所在的任何地方使用,但我们必须自己实现它的方法和属性。
class MyClass implements LibClass {
// our class will be a singleton too
private static _thisInstance: MyClass | undefined;
// not static, our instance will "own" the base instance
private _baseInstance: LibClass;
private constructor() {
this._baseInstance = LibClass.returnInstance();
}
public static returnInstance(): MyClass {
if ( ! MyClass._thisInstance ) {
MyClass._thisInstance = new MyClass();
}
return MyClass._thisInstance;
}
public method1(): number {
return this._baseInstance.method1();
}
public method2(): string {
return this._baseInstance.method2();
}
public myMethod(): number {
return this.method1() * 2;
}
}
class LibClass {
private static _instance: LibClass | undefined;
private constructor() {
}
public static returnInstance(): LibClass {
if ( ! LibClass._instance ) {
LibClass._instance = new LibClass();
}
return LibClass._instance;
}
public method1(): number {
return 5;
}
public method2(): string {
return "Hello World";
}
}
打字游戏场链接