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

新手上路,请多包涵

我想节省我的时间并在扩展 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);
        }
    }
}

When I do this.add() , I want the Game.Managers.Manager add() method to call a method which would exist on the object returned by 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 {

    }
}

我知道 IManagedObject 是一个接口,不能包含实现,但我不知道在我的 Texture 类中注入类 ObjectThatShouldAlsoBeExtended 应该写什么。知道 SpriteTilingSpriteLayer 等需要相同的过程。

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

原文由 Vadorequest 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 564
2 个回答

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

有关 TypeScript Mixin 的更多信息

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

这是一个快速的 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();

原文由 Fenton 发布,翻译遵循 CC BY-SA 3.0 许可协议

就我而言,我使用了 _串联继承_。也许对某人来说这种方式会有所帮助:

 class Sprite {
  x: number;
  y: number;

  constructor(x: number, y: number) {
    this.x = x;
    this.y = y;
  }
}

class Plane extends Sprite {
  fly(): string {
    return 'I can Fly!'
  }
}

class Enemy {
  isEnemy = true;
}

class Player {
  isPlayer = true;
}

// You can create factory functions to create new instances
const enemyPlane = Object.assign(new Plane(1, 1), new Enemy());
const playerPlane = Object.assign(new Plane(2, 2), new Player());

另外我推荐阅读 Eric Elliott 关于 js 继承的文章:

  1. 原型 OO 的核心与灵魂:串联继承
  2. 3 种不同的原型继承

原文由 zemil 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题