多重継承を考慮したほうがいいのかな
- カテゴリ:
- JavaScript
- コメント数:
- Comments: 0
◆ 言語機能的に多重継承はできない
◆ 任意クラスを継承したクラスを動的に作る仕組みが必要
◆ 継承して使う前提のクラスを export するモジュールを作る時 そこも考慮したほうがいいのかな
◆ 任意クラスを継承したクラスを動的に作る仕組みが必要
◆ 継承して使う前提のクラスを export するモジュールを作る時 そこも考慮したほうがいいのかな
普段あまり class は使ってないからかもしれませんが たまに使うと多重継承したくなりました
しかし JavaScript の仕組み自体に多重継承はないので 他の方法を取る必要があります
まずなにかすごい機能をもったベースクラスを作ったとします
この Base クラスを継承して specialMethod を色んなところで使いたいです
しかし すでに別のライブラリのクラスを継承しているクラスでも specialMethod を使いたいことがあります
LibBase と Base を両方継承できればいいのですができません
クラス B でどちらの機能も使いたいなら
のどちらかの継承関係にする必要があります
LibBase は外部ライブラリなので Base を継承させることは難しいので B -> Base -> LibBase の方にします
Base が継承する先が LibBase だけと固定なら単純に継承するだけですが 実際にはこれらは独立したもので多重継承したいからこうなっているだけです
LibBase の代わりにもいろいろなクラスが来ることが考えられます
そうなると動的に何でも継承できるようにしたほうが良いので こういう作りになります
LibBase などがなく単純に Base だけを継承したいときは
悪くはないですが こっちのほうがメインになりそうなのに 見た目的なわかりやすさが足りないかなと思ってこうしました
普通に Base を継承するなら そのまま Base を継承して Base を他を多重継承させたい場合は Base.extend 関数に継承先を入れます
使う側的には便利そうですが ライブラリ的なクラスを作るときに毎回こういう風にするのも面倒なんですよね
しかし JavaScript の仕組み自体に多重継承はないので 他の方法を取る必要があります
まずなにかすごい機能をもったベースクラスを作ったとします
export class Base {
specialMethod() {}
}
この Base クラスを継承して specialMethod を色んなところで使いたいです
class A extends Base {
method1() {
this.specialMethod()
}
}
しかし すでに別のライブラリのクラスを継承しているクラスでも specialMethod を使いたいことがあります
class B extends LibBase {
method1() {
// specialMethod 使いたい
}
}
LibBase と Base を両方継承できればいいのですができません
クラス B でどちらの機能も使いたいなら
B -> Base -> LibBase
B -> LibBase -> Base
のどちらかの継承関係にする必要があります
LibBase は外部ライブラリなので Base を継承させることは難しいので B -> Base -> LibBase の方にします
Base が継承する先が LibBase だけと固定なら単純に継承するだけですが 実際にはこれらは独立したもので多重継承したいからこうなっているだけです
LibBase の代わりにもいろいろなクラスが来ることが考えられます
そうなると動的に何でも継承できるようにしたほうが良いので こういう作りになります
export default Class => class extends (Class ?? class {}) {
specialMethod() {}
}
import extendBase from "./base.js"
class B extends extendBase(LibBase) {
method1() {
this.specialMethod()
}
}
LibBase などがなく単純に Base だけを継承したいときは
class B extends extendBase() {
method1() {
this.specialMethod()
}
}
悪くはないですが こっちのほうがメインになりそうなのに 見た目的なわかりやすさが足りないかなと思ってこうしました
const _Base = Class => class extends (Class ?? class {}) {
specialMethod() {}
}
const Base = _Base()
Base.extend = _Base
export default Base
import Base from "./base.js"
class B extends Base {
method1() {
this.specialMethod()
}
}
class C extends Base.extend(LibBase) {
method1() {
this.specialMethod()
}
}
普通に Base を継承するなら そのまま Base を継承して Base を他を多重継承させたい場合は Base.extend 関数に継承先を入れます
使う側的には便利そうですが ライブラリ的なクラスを作るときに毎回こういう風にするのも面倒なんですよね