継承
inheritance
継承のダメさ、変更の手間の問題もありそうと思ったmrsekut.icon
一つメソッドを生やすときの手間と、
継承されたものを分離して正しい形するための手間
が全く釣り合ってないのでは
(具体例を考えずに感覚で書いてるので全然そんなことない可能性はある)
知らないだけでIDEのサポートで簡単にできる可能性もある
「継承」という構造(概念?)自体が悪いわけではないのだと思う
理論的にはそこそこ正しいんじゃないか、しらんけど
ただ、それを表現するツールがショボいのが悪いのだと思う
求められる制約が多かったり、それの違反に気付きづらすぎだったり、
違反に気付いても修正が面倒だったり、
overrideしてるものなのかどうかがひと目で判断できなかったり
プログラマの認知に負担をかける要素が多すぎるのだろう
新しい言語機能が発見されたり、IDEのサポートが強化されれば割と使えたりするのではないか
しらんけど
defaultのOOP言語機能として提供される「継承」を作るための制約が弱すぎるmrsekut.icon
だから何でもかんでも継承にすることができるし、
実際それは原則を守っていないので、ゆくゆく破滅するということが生じる
契約プログラミングがなく、動的型付け言語で、チーム開発している、というような状況で、正しく継承をやっていくってほぼ不可能じゃない?という気がするmrsekut.icon
単純に知識がなかったり、疲弊してて思考力が鈍ってたりすればいとも簡単に。
故に「継承は禁止」としたほうが安心安全運用になる
基本的なこと
code:ts
class P {
constructor() {..}
f() {..}
h() {..}
}
class C extends P {
constructor() {
..
super(..)
}
g() {..}
h() {..}
}
C.g()が呼ばれた場合は、普通にC内のg()が呼ばれる
C.f()が呼ばれた場合は、Cにはないので、親であるPへメッセージが移譲され、Pのf()が応答する
h()は親で定義されているが、子でも定義されている(override)ので、Cの方のh()が呼ばれる
overraideしているにも関わらず、親の同名のmethodを呼びたい場合は、super()で呼ぶ
constructor()でやっているのがそれ
constructor()も1つのmethodであり、別に特別扱いされているわけではない
instantiateする際は、親のpropertyなども初期化する必要があるので、constructorとsuperは割とセットで使われるだけ
具体的に何が受け継がれる?
property, method全部?
methodなどは適当なアクセス修飾子を付けたら引き継がれない、みたいなのがあった気がする 再利用性以外の利点はなに?
継承って、継承しなくても、
子目線で、親となるはずだったものをDIして内部で使うこともできるはずだと思うけど、
あまり具体的にイメージできてないが、継承するはずだった親classをDIして使おうとするとかなり冗長になっちゃったりするのか?
traitを使うか、super classを使うかの判断って何でするの?
behaves-like-aか、is-aか
sub classはsuper classの全ての振る舞いを継承する
から、それが正しい状況でないといけない
こっちは知らんmrsekut.icon
クローンすることのことらしい
『オブジェクト指向設計実践ガイド』.icon p.167~ 親子間の結合度の話
superの返り値の型がstrirngなのか、objectなのかを知っていないと使えない
「superを送るのを忘れるとerrorになる」とか
関連
どこで継承を使うべきか?
継承元とはめちゃくちゃ密結合になるので、
継承元はほぼほぼ変更がないことを担保していて欲しい
hsの型クラスはかなり理想的mrsekut.icon
よく転がっているはず
また、型クラスにおける継承では、こういった問題が生じることを目にしたことが無いがなぜか?
単純に知らないだけで問題は起きているパターン
自分で継承することは少ないから問題は起きづらいパターン
このような(OOPでは失敗する)数学的な継承関係がうまく当てはまるから、というパターン
有名型クラスである、Monoid、Functorや、Monadとかは完全に数学的な構造に基づいて継承関係が決まっている
その他
どれ?
参考
もっともなことを言っていると思うmrsekut.icon