I have a class that extends another class. For example:
class Store extends BehaviorSubject {
constructor(obj) {
super(obj)
}
}
I also have more classes the extends Store
.
What I need is a way to hide some properties from the BehaviorSubject
superclass, for example, the next()
method.
class SomeStore extends Store {
}
// I want to hide from this class some methods, properties
// That exists on the BehaviorSubject class.
const s = new SomeStore();
There is a way to do this?
I have a class that extends another class. For example:
class Store extends BehaviorSubject {
constructor(obj) {
super(obj)
}
}
I also have more classes the extends Store
.
What I need is a way to hide some properties from the BehaviorSubject
superclass, for example, the next()
method.
class SomeStore extends Store {
}
// I want to hide from this class some methods, properties
// That exists on the BehaviorSubject class.
const s = new SomeStore();
There is a way to do this?
Share Improve this question asked Dec 22, 2017 at 6:19 undefinedundefined 6,87413 gold badges53 silver badges101 bronze badges 4- Yes, I want only the Store to know about this props. – undefined Commented Dec 22, 2017 at 6:22
-
There's no nice way to "hide" those properties. And I strongly remend reconsider the approach. It's better to not inherit at all from the
Store
directly, but instead wrap into a specially designed class which does not exposeStore
'snext()
and everything else you want to keep hidden. – Igor Soloydenko Commented Dec 22, 2017 at 6:25 - @Igor Can you give an example, please? – undefined Commented Dec 22, 2017 at 6:26
- I know you've already accepted another answer, but you can take a look at my variant of the code if you like. – Igor Soloydenko Commented Dec 22, 2017 at 6:54
2 Answers
Reset to default 9No. You can override the method in the subclass to do something else (or nothing) but this is violating the Liskov Substitution principle.
If your Store class is not a BehaviorSubject, and does not act like one, then extending is not correct. A Store should contain a private instance of BehaviorSubject in this case, and if necessary expose some of its methods/properties, by “proxying” them.
You can write something like the code below. There's also no inheritance, which is good. Passing the Store
object via constructor is a way to implement DIP (dependency inversion principle). It's good on its own, because it decouples classes and also makes StoreWrapper
testable.
Code
export class StoreWrapper {
constructor(private _store: Store) { }
// Expose things that you think are okay to expose...
getValue = this._store.getValue;
onCompleted = this._store.onCompleted;
onError = this._store.onError;
onNext = this._store.onNext;
// Anything that is not exposed similar to how it is done above, will be hidden
// next = this._store.next;
}
Usage
const originalStore = ...; // <--- this is your original `Store` object.
const wrappedStore = new StoreWrapper(originalStore);
const value = wrappedStore.getValue();
// ... and so on
Important Notes:
- While
this._store.next()
is still possible to invoke from within theStoreWrapper
, this code is not violating the LSP. In other words, it does not break the way inheritance is supposed to be used. - You can now test this
StoreWrapper
class very easily, in case it grows and gets some "meat" (logic).