打字符:如何扩展两个类?

2022-08-30 05:02:56

我想节省时间,并在扩展PIXI类(2d webGl渲染器库)的类之间重用通用代码。

对象接口:

module Game.Core {
    export interface IObject {}

    export interface IManagedObject extends IObject{
        getKeyInManager(key: string): string;
        setKeyInManager(key: string): IObject;
    }
}

我的问题是里面的代码不会改变,我想重用它,而不是复制它,这是实现:getKeyInManagersetKeyInManager

export class ObjectThatShouldAlsoBeExtended{
    private _keyInManager: string;

    public getKeyInManager(key: string): string{
        return this._keyInManager;
    }

    public setKeyInManager(key: string): DisplayObject{
        this._keyInManager = key;
        return this;
    }
}

我想做的是通过 管理器中使用的键自动添加,以在其属性中引用对象本身内部的对象。Manager.add()_keyInManager

因此,让我们以纹理为例。这是TextureManager

module Game.Managers {
    export class TextureManager extends Game.Managers.Manager {

        public createFromLocalImage(name: string, relativePath: string): Game.Core.Texture{
            return this.add(name, Game.Core.Texture.fromImage("/" + relativePath)).get(name);
        }
    }
}

当我这样做时,我希望该方法调用一个方法,该方法将存在于 返回的对象上。在本例中,此对象将是:this.add()Game.Managers.Manageradd()Game.Core.Texture.fromImage("/" + relativePath)Texture

module Game.Core {
    // I must extend PIXI.Texture, but I need to inject the methods in IManagedObject.
    export class Texture extends PIXI.Texture {

    }
}

我知道这是一个接口,不能包含实现,但我不知道该写什么来在我的类中注入类。知道 、 等需要相同的过程。IManagedObjectObjectThatShouldAlsoBeExtendedTextureSpriteTilingSpriteLayer

我在这里需要有经验的TypeScript反馈/建议,它必须有可能做到,但不是通过多次扩展,因为当时只有一个可能是可能的,我没有找到任何其他解决方案。


答案 1

TypeScript中有一个鲜为人知的功能,它允许您使用Mixins创建可重用的小对象。您可以使用多重继承将它们组合成更大的对象(类不允许多重继承,但允许mixins - 它们类似于具有关联增强的接口)。

有关 TypeScript Mixins 的更多信息

我认为您可以使用此技术在游戏中的许多类之间共享公共组件,并从游戏中的单个类中重用其中的许多组件:

这是一个快速的Mixins演示...首先,您想要混合的口味:

class CanEat {
    public eat() {
        alert('Munch Munch.');
    }
}

class CanSleep {
    sleep() {
        alert('Zzzzzzz.');
    }
}

然后是Mixin创建的神奇方法(您只需要在程序中的某个地方使用一次...

function applyMixins(derivedCtor: any, baseCtors: any[]) {
    baseCtors.forEach(baseCtor => {
        Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
             if (name !== 'constructor') {
                derivedCtor.prototype[name] = baseCtor.prototype[name];
            }
        });
    }); 
}

然后,您可以从 mixin 口味创建具有多重继承的类:

class Being implements CanEat, CanSleep {
        eat: () => void;
        sleep: () => void;
}
applyMixins (Being, [CanEat, CanSleep]);

请注意,此类中没有实际的实现 - 足以使其通过“接口”的要求。但是当我们使用这个类时 - 它一切都有效。

var being = new Being();

// Zzzzzzz...
being.sleep();

答案 2

我建议使用那里描述的新mixins方法:https://blogs.msdn.microsoft.com/typescript/2017/02/22/announcing-typescript-2-2/

这种方法比Fenton描述的“applyMixins”方法更好,因为自动编译器将帮助您并显示基类和第二继承类中的所有方法/属性。

可以在 TS Playground 网站上检查此方法。

下面是实现:

class MainClass {
    testMainClass() {
        alert("testMainClass");
    }
}

const addSecondInheritance = (BaseClass: { new(...args) }) => {
    return class extends BaseClass {
        testSecondInheritance() {
            alert("testSecondInheritance");
        }
    }
}

// Prepare the new class, which "inherits" 2 classes (MainClass and the cass declared in the addSecondInheritance method)
const SecondInheritanceClass = addSecondInheritance(MainClass);
// Create object from the new prepared class
const secondInheritanceObj = new SecondInheritanceClass();
secondInheritanceObj.testMainClass();
secondInheritanceObj.testSecondInheritance();