JavaScriptにおけるOOPの継承におけるプライベートプロパティの問題
プライベートプロパティが継承されないことにより、 予期しない問題が発生することがあります。 例を見てみましょう。 以下のようにプライベートプロパティを持つ 親クラスがあるとします:
class User {
#age;
setAge(age) {
this.#age = age;
}
getAge() {
return this.#age;
}
}
子クラスで、年齢を1つ増やすメソッドを 作成したいと考えたとします。 しかし、親クラスのプライベートプロパティを 変更しようとするとエラーが発生します:
class Student extends User {
incAge() {
this.#age++; // エラー
}
}
子クラスでプライベートプロパティ #age を
宣言すればエラーはなくなります:
class Student extends User {
#age;
incAge() {
this.#age++;
}
}
ここに落とし穴があります! 実際には、親クラスと子クラスに それぞれ別々のプライベートプロパティが 生成されてしまっています。 これらは完全に独立して動作します。 つまり、親クラスのメソッドは親クラスのプロパティを変更し、 子クラスのメソッドは子クラスのプロパティを変更する ことになります。
この問題には解決策があります。 親クラスのプライベートプロパティは、 その親クラスのメソッドを通じて操作すればよいのです。 この考え方に基づいてコードを書き直してみましょう:
class Student extends User {
incAge() {
let age = this.getAge();
age++;
this.setAge(age);
}
}
簡略化することもできます:
class Student extends User {
incAge() {
this.setAge(++this.getAge());
}
}
次のコードでは、子クラスで親クラスのメソッドが オーバーライドされています。 このコードの問題点を修正してください:
class User {
#name;
setName(name) {
this.#name = name;
}
getName() {
return this.#name;
}
}
class Employee extends User {
setName(name) {
if (name.length > 0) {
this.#name = name;
}
}
}