Joseph Allain
Joseph Allain

Reputation: 770

Inheritance of class arguments

I would like to make Bob a NPC with all NPC class parameters, and all Civil class parameters, but I don't know how to declare it so both Classes read the params associative array to define Bob properties.

My code:

class Civil {
  constructor(params) {
    params["gold"] ? this.gold = params["gold"] : this.gold = 0;
  }
}

class NPC extends Civil {
  constructor(params) {
    super();
    params["name"] ? this.name = params["name"] : this.name = "No name defined";
    params["race"] ? this.race = params["race"] : this.race = "No race defined";
  }
}

var bob = new NPC({
  "name": "Bob",
  "race": "Human",
  "gold": 10
});

console.log(bob.name);
//returns that "params" is undefined in Civil class

If I don't use params in the Civil class and simply set this.gold to an int, everything works, and Bob.gold returns the int, Bob.name returns "Bob", and Bob.race returns "Human".

It's one of the first time I experiment with classes (to make a small game), and I don't fully understand how class inheritance works.

Upvotes: 2

Views: 68

Answers (2)

el-teedee
el-teedee

Reputation: 1341

Also, based on Luca Kiebel's answer (missing params in super call) and Michelangelo's comment (use default arguments in constructor), I would rewrite like this:

class Civil {
  constructor(params = { "gold": 0 }) {
    this.gold = params["gold"];
  }
}

class NPC extends Civil {
  constructor(params = { name: "No name", race: "No race" } ) {
    super(params);
    this.name = params["name"];
    this.race = params["race"];
  }
}

var bob = new NPC({
  "name": "Bob",
  "race": "Human",
  "gold": 10
});
console.log("Name (NPC with custom params): " + bob.name); // Ok

bob = new NPC();
console.log("Name (NPC with default params): " + bob.name); // Ok, no error

You may get an error if you do not check for params existence / validity:

"message": "Uncaught TypeError: Cannot read property 'gold' of undefined"

class Civil {
  constructor(params) {
    this.gold = params["gold"] ? params["gold"] : 0; // <-- missing check "params" exists
  }
}

class NPC extends Civil {
  constructor(params) {
    super(params);
    this.name = params["name"] ? params["name"] : "No name defined";
    this.race = params["race"] ? params["race"] : "No race defined";
  }
}

var bob = new NPC({
  "name": "Bob",
  "race": "Human",
  "gold": 10
});
console.log("Name (NPC with custom params): " + bob.name); // Ok

bob = new NPC();
console.log("Name (NPC with default params): " + bob.name); // Error: Uncaught TypeError: Cannot read property 'gold' of undefined
                                   // in NDC constructor

Upvotes: 0

Luca Kiebel
Luca Kiebel

Reputation: 10096

Pass params to super(). Otherwise the class Civil is initiated without any parameters, and doesn't have access to those passed to NPC. Also, you can make the assignment of this variables a little shorter.

class Civil {
  constructor(params) {
    if(!params) throw new Error("Params must be set")
    this.gold = params["gold"] ? params["gold"] : 0;
  }
}

class NPC extends Civil {
  constructor(params) {
    if(!params) throw new Error("Params must be set")
    super(params); // <-- pass them here.
    this.name = params["name"] ? params["name"] : "No name defined";
    this.race = params["race"] ? params["race"] : "No race defined";
  }
}

var bob = new NPC({
  "name": "Bob",
  "race": "Human",
  "gold": 10
});

console.log(bob.name);
//returns that "params" is undefined in Civil class

Upvotes: 2

Related Questions