是否可以从另一个类内部调用一个类(不扩展)?

时间:2019-03-29 01:48:45

标签: javascript

我正在为基本游戏开发不同的组件。

现在,我的结构是我有一个种族类文件,该类被导出到另一个文件中,在该文件中我有一个人类类的扩展类并成为一个Player。赋予玩家人类和玩家的属性。

但是,这意味着如果我想创造一个非人类的玩家,我就必须制造出一个新的超越其他种族的玩家。这似乎是一种差劲的做法,我想找到一种方法来重构所有内容以使它更好地流动。


这是我的人类班级:

export class Human {
constructor() {
    this.type = 'Human';
    this.health = 10;
    this.baseAttack = 2;
    this.baseDefense = 1;
}

这是我的播放器播放器类:

export class Player extends Human {
constructor(name, level){
    super();
    var inventory = {};
    this.name = name;
    this.level = level;
    this.inventory = inventory;
    this.currentCapacity = 0;
    this.maxCapacity = 50;
}

Player类中还有其他与清单相关的功能,但是这些功能似乎与我的问题无关。


我的预期结果是,我有一组种族,当我创建一个玩家或一个角色时,我可以从该种族中进行选择,然后该玩家或角色将继承对该种族而言是静态的属性(例如,健康,baseAttack,和baseDefense)。

3 个答案:

答案 0 :(得分:3)

就像聪明的孩子所说的那样,更喜欢构图而不是继承。您可以做这样的事情而不会偏离您当前的方法:

class Orc {
  constructor() {
    this.mortal = true
  }
}

class Player {
constructor(race, name, level){
    var inventory = {};
    this.race = race;
    this.name = name;
    this.level = level;
    this.inventory = inventory;
    this.currentCapacity = 0;
    this.maxCapacity = 50;
    }
}

const orc = new Player(new Orc(), 'Baz', 1 )
console.log(orc.race)

还有很多其他方法可以为这只猫蒙皮,包括让人类从Player身上掉下来。实际上,这将是使用经典继承对那些实体建模的常用方法(Player是一般情况,而Humans和Orcs更具体)。

class PlayerClassic {
constructor(name, level){
    var inventory = {};
    this.name = name;
    this.level = level;
    this.inventory = inventory;
    this.currentCapacity = 0;
    this.maxCapacity = 50;
    }
}


class Human extends PlayerClassic {
  constructor(name, level) {
    super(name, level)
    this.mortal = true
  }
}

const human = new Human('Johnny', 2)
console.log(human)

我发现继承层次结构很少能带来很多好处。在上述两种情况下,您都必须使用typeof来确定您要处理的是哪种生物。

如果这是我的代码,我可能会完全跳过这些类。我可能会做以下类似的事情来建立一个表示构造好的播放器的数据结构:

const raceTemplates = {
  human: {mortal:true}, 
  elf: { mortal:true}}

const playerMaker = template => (race, name, level)=> {
  return {
    name,
    level,
    race,
    inventory: {},
    currentCapacity:0,
    maxCapacity:50,
    ...template[race]
  }
}  

const player = playerMaker(raceTemplates)('elf', 'sammy', 2)
console.log(player) 

这是对感兴趣的人的REPL.it的链接:

https://repl.it/@rmoskal/RealisticWholeParameter

答案 1 :(得分:0)

要回答标题中的问题:

  

一个类可以包含另一个类吗?

是的,可以。

否则,对于您的情况,我将race视为一个属性(类似地,玩家也可能具有品质,可能需要进行设置)。因此,我建议通过工厂方法注入值。只是提供了一个简单的突出显示,但是您可以自己构建更结构化的factory method

function raceFactory(raceName) {
    if (raceName == 'raceA') {
        let res = new Human();
        res.health = 30;
        return res;
    }
}

并在主应用中:

let humanRaceA = new factory.RaceFactory('raceA');

答案 2 :(得分:0)

这是另一种解决方案

function Player(name, level){
    var inventory = {};
    this.name = name;
    this.level = level;
    this.inventory = inventory;
    this.currentCapacity = 0;
    this.maxCapacity = 50;
}

module.exports.Player = function(race, name, level){
  var newPlayer = Object.create(Object.assign(race.prototype, Player.prototype))//override  
  race.call(newPlayer);
  Player.call(newPlayer, name, level);
  return newPlayer;
}

在客户端代码中,您可以执行以下操作:

var { Player } = require(/* your module */)
var newPlayer = Player(Human, 'Bob', 23);
console.log(newPlayer);
/*
{ type: 'Human',
  health: 10,
  baseAttack: 2,
  baseDefense: 1,
  name: 'Bob',
  level: 23,
  inventory: {},
  currentCapacity: 0,
  maxCapacity: 50 }
*/
相关问题