簡體   English   中英

是否可以從另一個類內部調用一個類(沒有擴展)?

[英]Is it possible to call a class from inside another class (without extending)?

我正在為基本游戲開發不同的組件。

現在我的結構是我有一個種族類的文件,它被導出到另一個文件,在那里我有一個類,它延伸到人類並制造一個玩家。 為玩家提供人類和玩家的屬性。

然而,這意味着如果我想制作一個不是人類的玩家,我將不得不制作一個新的玩家類別,而不是一個不同的種族。 這似乎是糟糕的做法,我想找到一種方法來重構它以使其更好地流動。


這是我的人類課程:

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類中還有與庫存相關的其他功能,但這些功能似乎與我的問題無關。


我的預期結果是我有一組種族,當我制作一個玩家或角色時,我可以從該組中選擇,然后該玩家或角色將繼承該種族的靜態屬性(例如health,baseAttack和baseDefense) 。

正如聰明的孩子所說,更喜歡作文和繼承。 你可以做這樣的事情而不偏離現有的方法:

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是一般情況,人類和獸人更具體)。

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

要在標題中回答您的問題:

一個類可以包含另一個類嗎?

是的,它可以。

否則,對於您的場景,我將race視為一種屬性(類似的玩家也可以具有品質,可能需要設置)。 因此,我建議通過工廠方法注入值。 只是提供了一個簡單的亮點,但您可以自己使用更結構化的factory method

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

並在主應用程序中:

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

這是另一種解決方案

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 }
*/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM