1

How would you do this without:

  • exposing the private property of the base class publicly through setters and getters such as in this answer
  • or having to duplicate any relevant methods and properties of the base class into the derived class

The properties should remain truly private except within the derived class declaration, so you can't use the protected variable underscore _ convention.

Suppose I have the following code

class CoffeeMachine {
  #waterLimit = 600;
  #waterAmount = 0;

  constructor() {}

  set waterAmount(amount) {
    if (amount < 0) {
      this.#waterAmount = 0;
    } else if (amount > this.#waterLimit) {
      this.#waterAmount = this.#waterLimit;
    } else {
      this.#waterAmount = amount;
    }
  }

  get waterAmount() {
    return this.#waterAmount;
  }
}

class TeaMachine extends CoffeeMachine {
  constructor() {
    super();
  }
}

I would like the TeaMachine to be smaller, so I want it's #waterLimit equal to 400 instead of 600

Simply doing the following doesn't work

class TeaMachine extends CoffeeMachine {
  #waterLimit = 400;
  constructor() {
    super();
  }
}

const teaBox = new TeaMachine();
teaBox.waterAmount = 1000;
console.log(teaBox.waterAmount); // 600

This is the closest I could get

The water limit is set on initiation, but is no longer accessible afterwards. Though obviously this is not a perfect solution

class CoffeeMachine {
  #waterLimit;
  #waterAmount = 0;

  constructor(limit = 600) {
    this.#waterLimit = limit;
  }
}

class TeaMachine extends CoffeeMachine {
  constructor() {
    super(400);
  }
}

const teaBox = new TeaMachine();
teaBox.waterAmount = 1000;
console.log(teaBox.waterAmount); // 400

I believe this is possible in Java

Is it even possible to do this in JavaScript while meeting the aforementioned conditions? Or will I have to just accept the restrictions of the language / go down the WeakMap route?

Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
Ruban Prakash
  • 83
  • 1
  • 7
  • 1
    In ECMAScript, `private` means private - no one else gets to see it but the class itself. Applying rules from one language to other languages is an exercise in frustration that I've never understood. If you go from playing baseball to playing basketball, you don't start hitting the balls with bats do you? You should accept the restrictions of the language and design your classes to fit those restrictions, not work around the restrictions with some jury-rigged system that someone else will have to ask about on SO a few years from now. – Heretic Monkey Aug 28 '21 at 12:43
  • 1
    Indeed, private field and method access doesn’t get “inherited” like for public fields and methods, so you will have to find a different approach. There’s some discussion about this in the original proposal: [Hard-private vs soft-private](//github.com/tc39/proposal-private-fields/issues/33), [Derived class access](//github.com/tc39/proposal-class-fields/issues/12), [Why is this ignoring common practices used in other object oriented languages?](//github.com/tc39/proposal-class-fields/issues/297). I’d question your design decision to make `TeaMachine` extend `CoffeeMachine` anyway. – Sebastian Simon Aug 28 '21 at 12:59

0 Answers0