【问题标题】:Instantiate an extended class from an instance of parent class - Typescript从父类的实例实例化扩展类 - Typescript
【发布时间】:2021-02-19 05:25:36
【问题描述】:

我使用了一个我想在 Typescript 中扩展的库。这个库有一个我扩展的类:

import lib from 'lib'

class MyClass extends lib.ItsClass {

}

该库还有一个返回其类实例的函数。我想从该实例创建我的类的实例。

const its_instance:lib.ItsClass = lib.returnInstance();

const myclass:MyClass = ...

如何在MyClass 的实例中转换its_instance

【问题讨论】:

    标签: typescript class inheritance prototype instance


    【解决方案1】:

    听起来基类正在使用Singleton Pattern。这是一种确保类只有一个实例的方法。

    以下是它通常如何工作的基本摘要。构造函数为private,因此不能通过调用new 创建实例,除非在类中。该类的唯一实例存储到private static 属性,其名称类似于instance。当您调用public static method returnInstance() 时,它会检查是否已设置instance 属性。如果没有,它会调用new 来创建实例,然后在返回之前将其保存到变量中。

    单例并不是真正为扩展而设计的。这个类很可能使用了private 方法和属性,尽管在Javascript 中private 更多的是建议而不是规则。

    另一个问题是应该只有一个实例,但现在您有两个不完全兼容的版本。如果基方法首先调用returnInstance() 并将实例设置为基类,那么这会给您的扩展类带来问题。

    解决此问题的一种方法是将扩展类的实例存储在不同的属性名称下并具有两个单独的实例,但现在您的实例和基实例彼此分离并具有单独的状态。

    最终,最简洁的方法是包装类而不是扩展它。您的类在内部存储对基类实例的引用(或者它可以只调用 LibClass.getInstance() 每次)。它模仿基类的方法,但将实际执行委托给基类实例。

    因为打字稿类也是接口,我们可以说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";
        }
    }
    

    Typescript Playground Link

    【讨论】:

    • 实际上它不是单例,它只是一个返回实例或实例数组的函数。最后,我在子类实例中使用了父类实例的引用。正如你所建议的那样。
    猜你喜欢
    • 2013-07-04
    • 1970-01-01
    • 2015-02-01
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多