I have a Heap class that has a private values
field. This is good since I do not want anyone to be able to directly modify values
.
class Heap {
#values;
constructor(array = []) {
this.#values = array;
}
insert(item) {
this.#values.push(item);
this.#bubbleUp(this.#values.length - 1);
}
}
But now I would like to extend my Heap class into a PriorityQueue subclass. In this class I need to change the signature of some of the methods (for example insert
) so that it assigns a priority to a value. However, I cannot figure out how to access the values
field from the base class. For instance, given the following PriorityQueue class:
class PriorityQueue extends Heap {
constructor(array = []) {
super(array);
}
insert(item, priority) {
// Error: Private field '#values' must be declared in an enclosing class
this.#values.push({ item, priority });
this.#bubbleUp(this.#values.length - 1);
}
}
I get an error when trying to push a value onto values
.
Is there any way around this problem? I want to make a field private in the base class, but still accessible to the subclass.
Thanks!
I have a Heap class that has a private values
field. This is good since I do not want anyone to be able to directly modify values
.
class Heap {
#values;
constructor(array = []) {
this.#values = array;
}
insert(item) {
this.#values.push(item);
this.#bubbleUp(this.#values.length - 1);
}
}
But now I would like to extend my Heap class into a PriorityQueue subclass. In this class I need to change the signature of some of the methods (for example insert
) so that it assigns a priority to a value. However, I cannot figure out how to access the values
field from the base class. For instance, given the following PriorityQueue class:
class PriorityQueue extends Heap {
constructor(array = []) {
super(array);
}
insert(item, priority) {
// Error: Private field '#values' must be declared in an enclosing class
this.#values.push({ item, priority });
this.#bubbleUp(this.#values.length - 1);
}
}
I get an error when trying to push a value onto values
.
Is there any way around this problem? I want to make a field private in the base class, but still accessible to the subclass.
Thanks!
Share Improve this question asked Oct 31, 2021 at 20:21 EspressoEspresso 93020 silver badges39 bronze badges 2-
1
Just call the parent's
insert
method?super.insert({ item, priority })
. – Felix Kling Commented Oct 31, 2021 at 20:23 - "I want to make a field private in the base class, but still accessible to the subclass." that is what protected access is. However, JS doesn't have that for now. So you whatever you want to use in subclasses has to be public. – VLAZ Commented Oct 31, 2021 at 20:25
1 Answer
Reset to default 7I cannot figure out how to access the
values
field from the base class.
This is not possible. Private really means private in JS. Don't use it if you want the field to be accessible outside of the class.
I want to make a field private in the base class, but still accessible to the subclass.
That would be a protected member, which JS doesn't support.
Is there any way around this problem?
Well, you don't actually need to access the .#values
. All you need to do is call the base class insert
method:
class PriorityQueue extends Heap {
insert(item, priority) {
super.insert({ item, priority });
}
}
I would like to extend my
Heap
class into aPriorityQueue
subclass. In this class I need to change the signature of some of the methods (for example insert) so that it assigns a priority to a value.
This is a bad idea. A subclass should not change the method signatures, otherwise it will violate the Liskov substitution principle. Instead, use position over inheritance, where a priority queue has or contains a heap:
class PriorityQueue {
#heap = new Heap(v => v.priority); // assuming it takes a custom parator?
push(item, priority) {
this.#heap.insert({ item, priority });
}
pop() {
return this.#heap.…
}
}