Home > Software engineering >  how to create a method which creates new instance from class?
how to create a method which creates new instance from class?

Time:01-31

I have Bmw class extended from Car class I created before, now I need to create a createNewBmwCar method inside Bmw class which will create new instance from Bmw class...

class Bmw extends Car {
  constructor(options) {
    this._model = options.model;
    this._year = options.year;
    this._price = options.price;
  }
  static createNewBmwCar() {
    // return FIXME: let newCar = new Bmw();
  }
}

CodePudding user response:

You will need to instantiate Bmw in this static method:

class Car {};

class Bmw extends Car {
  constructor(options) {
    super(options);
    this._model = options.model;
    this._year = options.year;
    this._price = options.price;
  }
  static createNewBmwCar(options) {
    return new Bmw({
        model: "BMW",
        year: options.year,
        price: options.price
    });
  }
}

let myBMW = Bmw.createNewBmwCar({
    year: 2020,
    price: "1$"
});

console.log(myBMW);

CodePudding user response:

The problem isn't the static method, it's the constructor. Derived constructors must call super(), and must do so before they can use this.

If you fix that, and add the necessary parameter(s) to createNewBmwCar, it works (but keep reading):

class Car { }
class Bmw extends Car {
    constructor(options) {
        super(); // <=========
        this._model = options.model;
        this._year = options.year;
        this._price = options.price;
    }
    static createNewBmwCar(options) {
        let newCar = new Bmw(options);
        return newCar;
    }
}

const beemer = Bmw.createNewBmwCar({
    model: "fancy",
    year: "recent",
    price: "lots",
});
console.log(beemer._model); // "fancy"

You do have a second option that may be more flexible: You can use this instead of Bmw in the static method, since it will refer to the constructor you call the static method on:

static createNewBmwCar(options) {
    let newCar = new this(options);
    //               ^^^^
    return newCar;
}

class Car { }
class Bmw extends Car {
    constructor(options) {
        super(); // <=========
        this._model = options.model;
        this._year = options.year;
        this._price = options.price;
    }
    static createNewBmwCar(options) {
        let newCar = new Bmw(options);
        return newCar;
    }
}

const beemer = Bmw.createNewBmwCar({
    model: "fancy",
    year: "recent",
    price: "lots",
});
console.log(beemer._model); // "fancy"

That has the advantage that if you create a subclass of Bmw, and then call the static method on the subclass, you'll get an instance of the subclass, rather than a Bmw:

class Car { }
class Bmw extends Car {
    constructor(options) {
        super(); // <=========
        this._model = options.model;
        this._year = options.year;
        this._price = options.price;
    }
    static createNewBmwCar(options) {
        let newCar = new this(options);
        return newCar;
    }
}
class BmwSpecial extends Bmw { }

const beemer = BmwSpecial.createNewBmwCar({
    model: "fancy",
    year: "recent",
    price: "lots",
});
console.log(beemer instanceof BmwSpecial); // true, would be false with the earlier version

  •  Tags:  
  • Related