前スレ
オブジェクト指向はオワコン?
https://mevius.5ch.io/test/read.cgi/tech/1721393540/
オブジェクト指向はオワコン? part2
■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん
2026/08/13(木) 14:38:03.02ID:pdAcKRXu152デフォルトの名無しさん
2026/08/15(土) 16:01:21.42ID:oBPlyySV153デフォルトの名無しさん
2026/08/15(土) 16:10:40.42ID:fSG6hCiZ C++ だと通常メンバ変数と仮想メンバ変数でどちらのケースもあるから、C++を知っていればすぐに分かる話だけれど、
どちらかしかない言語を習得した人だと、どちらかのケースを元に考えるから分かりにくいんだろうな。
C++の通常メンバ変数=GoやRustのメソッド
現在の型によって決まるメソッド。キャストされたら呼ばれるメソッドが変わる。
ソースコード上、使用時の型は静的に決定できるので、コンパイル時に呼ばれるメソッドも固定される。
C++の仮想メンバ関数=Javaのメソッド
インスタンス生成時の型によって決まるメソッド。キャストされても呼ばれるメソッドは変わらない。
ソースコード上、インスタンス生成時の本当の型を決定できないので、コンパイル時に呼ばれるメソッドを特定できない。
どちらかしかない言語を習得した人だと、どちらかのケースを元に考えるから分かりにくいんだろうな。
C++の通常メンバ変数=GoやRustのメソッド
現在の型によって決まるメソッド。キャストされたら呼ばれるメソッドが変わる。
ソースコード上、使用時の型は静的に決定できるので、コンパイル時に呼ばれるメソッドも固定される。
C++の仮想メンバ関数=Javaのメソッド
インスタンス生成時の型によって決まるメソッド。キャストされても呼ばれるメソッドは変わらない。
ソースコード上、インスタンス生成時の本当の型を決定できないので、コンパイル時に呼ばれるメソッドを特定できない。
154デフォルトの名無しさん
2026/08/15(土) 16:16:03.46ID:silBGnFG >>151
まともなAIを使っても使う側がまともじゃなければ意味なかったな
まともなAIを使っても使う側がまともじゃなければ意味なかったな
155デフォルトの名無しさん
2026/08/15(土) 16:16:45.06ID:fSG6hCiZ >>153
> C++ だと通常メンバ変数と仮想メンバ変数でどちらのケースもあるから、C++を知っていればすぐに分かる話だけれど、
> C++の通常メンバ変数=GoやRustのメソッド
あ、しまった、関数を変数と間違えて書いてしまった。
通常メンバ関数と仮想メンバ関数、に訂正。
> C++ だと通常メンバ変数と仮想メンバ変数でどちらのケースもあるから、C++を知っていればすぐに分かる話だけれど、
> C++の通常メンバ変数=GoやRustのメソッド
あ、しまった、関数を変数と間違えて書いてしまった。
通常メンバ関数と仮想メンバ関数、に訂正。
156デフォルトの名無しさん
2026/08/15(土) 16:18:44.23ID:silBGnFG157デフォルトの名無しさん
2026/08/15(土) 16:25:53.62ID:+6/lj6CD158デフォルトの名無しさん
2026/08/15(土) 16:31:59.68ID:r7+Cc7Q7 C#でもデフォルト実装を書き換えるなら元のデフォルト実装を呼び出せないってさ
再帰定義になるため不可能とのこと
問題を引き起こすのはJavaだけの問題みたいね
再帰定義になるため不可能とのこと
問題を引き起こすのはJavaだけの問題みたいね
159デフォルトの名無しさん
2026/08/15(土) 16:41:03.86ID:0WCtanUv160デフォルトの名無しさん
2026/08/15(土) 16:42:09.41ID:r7+Cc7Q7 Rustでもデフォルト実装を書き換えるなら元のデフォルト実装を呼び出せないってさ
再帰定義になるため不可能とのこと
再帰定義になるため不可能とのこと
161デフォルトの名無しさん
2026/08/15(土) 16:42:48.33ID:S4+pqC1p162デフォルトの名無しさん
2026/08/15(土) 16:43:49.96ID:0WCtanUv >>141
そのレスはID:Yv1XFEHU(二代目複おじ)のほうでID:TQSPkWiNはまた別のやつだろう
そのレスはID:Yv1XFEHU(二代目複おじ)のほうでID:TQSPkWiNはまた別のやつだろう
163デフォルトの名無しさん
2026/08/15(土) 16:44:51.38ID:0WCtanUv >>160
問題のフレーミングが間違ってるからAIから間違った答えしか引き出せないんだよ
問題のフレーミングが間違ってるからAIから間違った答えしか引き出せないんだよ
164デフォルトの名無しさん
2026/08/15(土) 16:51:14.97ID:Fg8L11Lx165デフォルトの名無しさん
2026/08/15(土) 17:05:20.37ID:g+lgHL/9 Rustはクラス継承に相当するものがないからスーパーメソッド呼び出しがそもそもなくて問題が起きないわけだけど
C#はクラス継承もスーパーメソッド呼び出しもあるにも関わらずインターフェースでは使えない言語仕様だから問題が起きない
Javaはインターフェースでもスーパーメソッド呼び出しを使える間違った言語仕様にしたので問題が起きてる
C#はクラス継承もスーパーメソッド呼び出しもあるにも関わらずインターフェースでは使えない言語仕様だから問題が起きない
Javaはインターフェースでもスーパーメソッド呼び出しを使える間違った言語仕様にしたので問題が起きてる
166デフォルトの名無しさん
2026/08/15(土) 17:17:01.46ID:TQSPkWiN >>161
なるほど、勉強になります、あなた只者じゃないですね
なるほど、勉強になります、あなた只者じゃないですね
167デフォルトの名無しさん
2026/08/15(土) 17:32:13.56ID:2vg9s13q168デフォルトの名無しさん
2026/08/15(土) 17:36:22.11ID:TQSPkWiN169デフォルトの名無しさん
2026/08/15(土) 17:40:54.70ID:ILo7VsC4170デフォルトの名無しさん
2026/08/15(土) 17:46:09.20ID:nidKMiVb >>168
他でも問題が起きると言うならC#やRustで実例コードを作ってみてよ
他でも問題が起きると言うならC#やRustで実例コードを作ってみてよ
171デフォルトの名無しさん
2026/08/15(土) 17:47:39.14ID:fSG6hCiZ C# は使ったことがなかったんで知らなかったが、
C# でも virtual / override を付けるか付けないかでオーバーライドするしないを制御できるから、
C# を習得していても分かる話だな。
>>165
C# でも、<インタフェイス名>.<メソッド名> でメソッドの実装をすると、オーバーライドできるみたい。
あと、インターフェイス間ではクラスと同様に virtual / override でオーバーライドできるみたい。
Java と違って気付かずにオーバライドしていた、なんてことは起きないけど、
気づかずにそのメソッドを使用しているメソッドの挙動を変えていた、ということは発生する可能はあるね。
C# でも virtual / override を付けるか付けないかでオーバーライドするしないを制御できるから、
C# を習得していても分かる話だな。
>>165
C# でも、<インタフェイス名>.<メソッド名> でメソッドの実装をすると、オーバーライドできるみたい。
あと、インターフェイス間ではクラスと同様に virtual / override でオーバーライドできるみたい。
Java と違って気付かずにオーバライドしていた、なんてことは起きないけど、
気づかずにそのメソッドを使用しているメソッドの挙動を変えていた、ということは発生する可能はあるね。
172デフォルトの名無しさん
2026/08/15(土) 17:52:19.39ID:nt5T4P0f 抽象クラスは基本的に使用禁止にしてるけどサービスロケータでは例外として今でも使ってるわ
中を隠蔽しないように用途を限れば便利なのは違いない
中を隠蔽しないように用途を限れば便利なのは違いない
173デフォルトの名無しさん
2026/08/15(土) 17:53:45.32ID:TQSPkWiN174デフォルトの名無しさん
2026/08/15(土) 18:05:32.04ID:nt5T4P0f クラス委譲のある言語 いいなあ
便利なんだろうなあ
便利なんだろうなあ
175デフォルトの名無しさん
2026/08/15(土) 18:09:12.27ID:Xb26COoO >>171
クラスではなくてインターフェースのデフォルト実装の時の話だよ
クラスではなくてインターフェースのデフォルト実装の時の話だよ
176デフォルトの名無しさん
2026/08/15(土) 18:24:42.13ID:H74NynC0 self-use of overridable methodっていう有名パターンなのに知らないやつが多すぎやろw
昔々から初心者が2冊目に読むような本で紹介されてる基本中の基本やで〜
昔々から初心者が2冊目に読むような本で紹介されてる基本中の基本やで〜
177デフォルトの名無しさん
2026/08/15(土) 18:30:34.10ID:H74NynC0 Rustで発生するFragile Base Class Problemの一例
trait PointCalculator {
fn regular_point(&self, payment_amount: i32) -> i32;
fn campaign_point(&self, payment_amount: i32) -> i32 {
self.regular_point(payment_amount) * 2
}
fn super_campaign_point(&self, payment_amount: i32) -> i32 {
self.regular_point(payment_amount) * 4
// self.campaign_point(payment_amount) * 2 //<== こういう変更をすると継承先が壊れる可能性がある
}
}
https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=84769fbdb0fc90ba597cb86c8c2ed9d4
trait PointCalculator {
fn regular_point(&self, payment_amount: i32) -> i32;
fn campaign_point(&self, payment_amount: i32) -> i32 {
self.regular_point(payment_amount) * 2
}
fn super_campaign_point(&self, payment_amount: i32) -> i32 {
self.regular_point(payment_amount) * 4
// self.campaign_point(payment_amount) * 2 //<== こういう変更をすると継承先が壊れる可能性がある
}
}
https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=84769fbdb0fc90ba597cb86c8c2ed9d4
178デフォルトの名無しさん
2026/08/15(土) 18:31:56.78ID:H74NynC0 クラス継承で発生する問題の原因と対策を知らないからクラスという名前を持つ言語要素のないRustなどの言語でも同種の問題が発生するかどうかも分かってないんだよな
反省して勉強してね〜
反省して勉強してね〜
179デフォルトの名無しさん
2026/08/15(土) 18:34:06.19ID:H74NynC0 あ、ちなみにRustはインターフェースのデフォルト実装を上書き禁止にできない欠点があるよ
中の人はそれを理解してるから今後機能拡張される予定ではあるけど
中の人はそれを理解してるから今後機能拡張される予定ではあるけど
180デフォルトの名無しさん
2026/08/15(土) 18:49:30.39ID:FRwuYJVI181デフォルトの名無しさん
2026/08/15(土) 19:01:27.59ID:nt5T4P0f Javaだって final、private、protected abstractを守れば継承抽象化したって大きな問題無い
override可能な箇所を必要最小限にして親クラスが守るべき不変条件を finalやprivate で閉じ込めてやるのが大事なんよ
override可能な箇所を必要最小限にして親クラスが守るべき不変条件を finalやprivate で閉じ込めてやるのが大事なんよ
182デフォルトの名無しさん
2026/08/15(土) 19:03:36.72ID:nt5T4P0f >>174
ちょっと言い方ミスってんな 例えばKotlinのbyみたいな手軽な書き方ができるといいなってことを言いたかった
ちょっと言い方ミスってんな 例えばKotlinのbyみたいな手軽な書き方ができるといいなってことを言いたかった
183デフォルトの名無しさん
2026/08/15(土) 19:04:49.04ID:sXETHyYr184デフォルトの名無しさん
2026/08/15(土) 19:11:50.06ID:TQSPkWiN >>170
C#だとこうかな
static class Program {
private static void Main(string[] args) {
IPointCalculator calc = new GochanPointCalculator();
Console.WriteLine(calc.RegularPoint(10000));
Console.WriteLine(calc.CampaignPoint(10000));
}
}
interface IPointCalculator {
int RegularPoint(int paymentAmount) {
return paymentAmount / 100;
}
int CampaignPoint(int paymentAmount) {
return RegularPoint(paymentAmount) * 2;
}
}
class GochanPointCalculator : IPointCalculator {
public int RegularPoint(int paymentAmount) {
return paymentAmount / 100 + 10;
}
}
C#だとこうかな
static class Program {
private static void Main(string[] args) {
IPointCalculator calc = new GochanPointCalculator();
Console.WriteLine(calc.RegularPoint(10000));
Console.WriteLine(calc.CampaignPoint(10000));
}
}
interface IPointCalculator {
int RegularPoint(int paymentAmount) {
return paymentAmount / 100;
}
int CampaignPoint(int paymentAmount) {
return RegularPoint(paymentAmount) * 2;
}
}
class GochanPointCalculator : IPointCalculator {
public int RegularPoint(int paymentAmount) {
return paymentAmount / 100 + 10;
}
}
185デフォルトの名無しさん
2026/08/15(土) 19:30:03.40ID:TQSPkWiN186デフォルトの名無しさん
2026/08/15(土) 20:04:10.46ID:fSG6hCiZ すみません。>>153 は、Rust について間違いでした。
Rust のデフォルト・メソッドはオーバーライドされます。
キャストした時でもインスタンス化した時の型に定義したメソッドが呼ばれます。
1. dyn を使ってキャストした場合は vtable が作成され、動的に解決されます。
2. >>177 の通り、デフォルト・メソッドを使ったメソッドにおいても、impl Trait for Struct に実装したメソッドが使われます。
3. 以下のようにしても、impl Trait for Struct に実装したメソッドが呼ばれます。
var instance = Struct::new();
Trait::method(&instance);
1.はともかく、2.と3.について完全に誤解していました。🙇
Rust のデフォルト・メソッドはオーバーライドされます。
キャストした時でもインスタンス化した時の型に定義したメソッドが呼ばれます。
1. dyn を使ってキャストした場合は vtable が作成され、動的に解決されます。
2. >>177 の通り、デフォルト・メソッドを使ったメソッドにおいても、impl Trait for Struct に実装したメソッドが使われます。
3. 以下のようにしても、impl Trait for Struct に実装したメソッドが呼ばれます。
var instance = Struct::new();
Trait::method(&instance);
1.はともかく、2.と3.について完全に誤解していました。🙇
187デフォルトの名無しさん
2026/08/15(土) 20:29:02.06ID:S4+pqC1p どう転んでも、どんな言語であっても、期待されないことを書くことはできる。
extendsやjavaがevilなのではなく、プログラミング言語がevilなのだ。
基本クラスで継承可能なメソッドを使うなということでもなく、
継承可能なメソッドでなければならない設計もある。
意図を初心者でもわかるように明記すること。そして意図を検証するunittestがあること。
継続的にインテグレーションテストができること。
ともかく、ソフトウェア工学の進歩に追いつけていないメインフレーム系のメーカーや、
どうしようもない教育しかうけていないプログラマーがいる限り、闘いは続く。
extendsやjavaがevilなのではなく、プログラミング言語がevilなのだ。
基本クラスで継承可能なメソッドを使うなということでもなく、
継承可能なメソッドでなければならない設計もある。
意図を初心者でもわかるように明記すること。そして意図を検証するunittestがあること。
継続的にインテグレーションテストができること。
ともかく、ソフトウェア工学の進歩に追いつけていないメインフレーム系のメーカーや、
どうしようもない教育しかうけていないプログラマーがいる限り、闘いは続く。
188デフォルトの名無しさん
2026/08/15(土) 20:40:13.32ID:2hYalLTI そもそもインターフェースって継承のための抽象化というより依存性逆転とかテスト時の差し替え可能性を確保するために使うものくらいに考えてる
とりあえずインターフェース切っとけで実装クラスと1:1対応させるのはむしろ抽象化を増やしてるだけでは
とりあえずインターフェース切っとけで実装クラスと1:1対応させるのはむしろ抽象化を増やしてるだけでは
189デフォルトの名無しさん
2026/08/15(土) 20:43:09.49ID:lG8RMaHa そういうわけでクラスは不要でインターフェースだけあればよいとわかった
それがモダンな言語の仕様に反映されている
それがモダンな言語の仕様に反映されている
190デフォルトの名無しさん
2026/08/15(土) 21:13:29.52ID:vxBg0KLF イベントドリブンなオブジェクトだらけになる
191デフォルトの名無しさん
2026/08/15(土) 21:22:20.54ID:GQznZi9p >>186
その通りでRustはdyn宣言しない限りどのメソッドも単相化されて普通の関数呼び出しと同じになりゼロコストで実行されて速い
dyn宣言した時のみ動的ディスパッチになり各型のvtableを引いて呼ぶ関数を決める
その通りでRustはdyn宣言しない限りどのメソッドも単相化されて普通の関数呼び出しと同じになりゼロコストで実行されて速い
dyn宣言した時のみ動的ディスパッチになり各型のvtableを引いて呼ぶ関数を決める
192デフォルトの名無しさん
2026/08/15(土) 22:59:10.16ID:nt5T4P0f >>189
それは実装継承が不要ってことをクラスが不要ってことに飛躍させてるよ
Rustだってtraitだけで完結させてるわけじゃなくてstructとimplで状態と振る舞いを分けてる
Javaのclassの責務を別のものに分解しただけなんよ
もちろんclassという大きな責務を分割するのは良いことだよ
それは実装継承が不要ってことをクラスが不要ってことに飛躍させてるよ
Rustだってtraitだけで完結させてるわけじゃなくてstructとimplで状態と振る舞いを分けてる
Javaのclassの責務を別のものに分解しただけなんよ
もちろんclassという大きな責務を分割するのは良いことだよ
193デフォルトの名無しさん
2026/08/15(土) 23:04:20.24ID:AbqGm+Ug >>180>>183
複おじはRust信者なのにRust読めないの?
複おじはRust信者なのにRust読めないの?
194デフォルトの名無しさん
2026/08/15(土) 23:11:30.09ID:M3QQ7wMC195デフォルトの名無しさん
2026/08/15(土) 23:55:19.69ID:pd5pYsOL >>194
それは現在のRustが2015年に登場するよりもっと遥か昔の色んなことを試行錯誤していたRust未完成の時代の話だぞ
それは現在のRustが2015年に登場するよりもっと遥か昔の色んなことを試行錯誤していたRust未完成の時代の話だぞ
196デフォルトの名無しさん
2026/08/16(日) 00:31:09.64ID:0CvMbO4G >>194
「構造体 + メソッド = クラス」なんだから当然だな
「構造体 + メソッド = クラス」なんだから当然だな
197デフォルトの名無しさん
2026/08/16(日) 00:33:05.01ID:poIe7pLM198デフォルトの名無しさん
2026/08/16(日) 10:04:08.54ID:tjwwNDs7199デフォルトの名無しさん
2026/08/16(日) 10:09:53.00ID:J2pSiYC1 クラス継承なんかしないで
使いたいクラスを取り込めばいいだけ
使いたいクラスを取り込めばいいだけ
200デフォルトの名無しさん
2026/08/16(日) 10:43:43.08ID:sS+cH1fU201デフォルトの名無しさん
2026/08/16(日) 10:55:36.25ID:a4RxNiOb インラインで展開かw
202デフォルトの名無しさん
2026/08/16(日) 11:02:38.33ID:Okvwqdtm >>200
Rustでは問題起きないよ
Rustでは問題起きないよ
203デフォルトの名無しさん
2026/08/16(日) 11:29:32.30ID:Q/5wpQBy クラスが悪ってのはさすがに行きすぎな気がするがな
そのレベルでダメならどんな概念もこじつけで悪いものにできると思うわ。
そのレベルでダメならどんな概念もこじつけで悪いものにできると思うわ。
204デフォルトの名無しさん
2026/08/16(日) 11:32:41.10ID:BRHsau7p 巨大なピラミッドになるクラス継承を使わなければ大丈夫よ
205デフォルトの名無しさん
2026/08/16(日) 11:58:04.41ID:8yz0P3zw ハル夫くんは反復ばかりで話が発展しないのどうにかして
206デフォルトの名無しさん
2026/08/16(日) 12:04:44.76ID:4EyRDcWH クラスが悪というかクラスに責務を詰め込みすぎたというか
207デフォルトの名無しさん
2026/08/16(日) 12:25:04.76ID:8yz0P3zw オブジェクト指向らしくデザインパターンという形で整理するのが良い気がする
とりあえず動くシンプルなものを作るためのデザインパターン
staticおじさんパターンとかね
とりあえず動くシンプルなものを作るためのデザインパターン
staticおじさんパターンとかね
208デフォルトの名無しさん
2026/08/16(日) 13:07:18.35ID:Y1CXBzVZ デザインパターン系も継承関係はクラス継承よりインターフェース継承が良いですよパターン
209デフォルトの名無しさん
2026/08/16(日) 13:20:43.77ID:8yz0P3zw210デフォルトの名無しさん
2026/08/16(日) 13:26:23.74ID:+BV6GwVc >>209
クラス継承よりコンポジションな
クラス継承よりコンポジションな
211デフォルトの名無しさん
2026/08/16(日) 13:34:13.73ID:FW6ktTKM >>209
GoFのデザインパターンにそんなこと書かれてないぞ
GoFのデザインパターンにそんなこと書かれてないぞ
212デフォルトの名無しさん
2026/08/16(日) 13:42:39.48ID:nyOyVcBG >>209
GoFのデザインパターンはインターフェース継承を使おうという話で構成されてる
例えばStrategyパターンはインターフェース継承で抽象化しておけば簡単に切り替えららるよという話
Template Methodパターンは振る舞いははインターフェースで決めておいてインターフェース継承した各型が実装する話
VisitorパターンはVisitorインターフェースを作っておいてそれを実装する各型へディスパッチする話
GoFのデザインパターンはインターフェース継承を使おうという話で構成されてる
例えばStrategyパターンはインターフェース継承で抽象化しておけば簡単に切り替えららるよという話
Template Methodパターンは振る舞いははインターフェースで決めておいてインターフェース継承した各型が実装する話
VisitorパターンはVisitorインターフェースを作っておいてそれを実装する各型へディスパッチする話
213デフォルトの名無しさん
2026/08/16(日) 14:06:41.06ID:8yz0P3zw214デフォルトの名無しさん
2026/08/16(日) 14:06:53.11ID:a4RxNiOb あんなくちゃくちゃした書き方をなでもかんでもしなくてもいいだろ>デザインパターン
いや、しない方が良いだろ
いや、しない方が良いだろ
215デフォルトの名無しさん
2026/08/16(日) 14:07:35.06ID:a4RxNiOb もう、エンタープライズに続く道再びだな
216デフォルトの名無しさん
2026/08/16(日) 14:08:55.86ID:8yz0P3zw ハル夫くんの反復横跳びを眺めるスレッド
217デフォルトの名無しさん
2026/08/16(日) 14:10:06.00ID:a4RxNiOb ttps://qiita.com/mogamoga1337/items/564a3d657a80e396dae1
218デフォルトの名無しさん
2026/08/16(日) 14:12:31.99ID:a4RxNiOb ttps://www.reddit.com/r/programming/comments/qkqghu/github/?tl=ja
219デフォルトの名無しさん
2026/08/16(日) 14:22:23.29ID:8yz0P3zw220デフォルトの名無しさん
2026/08/16(日) 14:23:32.50ID:a4RxNiOb カルトだ、見るとPTSDになりそうとかえらい言われようだけど
正直だと思う
正直だと思う
221デフォルトの名無しさん
2026/08/16(日) 14:26:52.76ID:a4RxNiOb >>219
同意だな、関数型で関数変換し細分化されていくにしたがって
ビックリするくらいシンプルな関数になっていくことがあるのには目を見張った。
複合型も必要性がなくなるというか、細分化の過程でシンプルな局所変数や引数のcall treeのscopeの中に構成されていくような不思議な感覚
同意だな、関数型で関数変換し細分化されていくにしたがって
ビックリするくらいシンプルな関数になっていくことがあるのには目を見張った。
複合型も必要性がなくなるというか、細分化の過程でシンプルな局所変数や引数のcall treeのscopeの中に構成されていくような不思議な感覚
222デフォルトの名無しさん
2026/08/16(日) 14:28:36.72ID:a4RxNiOb ただ、毎回何でもかんでもうまくいくとは限らないし
再帰や関数変化の考え方など頭に少し負担がかかる
再帰や関数変化の考え方など頭に少し負担がかかる
223デフォルトの名無しさん
2026/08/16(日) 14:36:36.64ID:9AyjbUVF デザインパターンのうち複数の型が出てくるものは二つのパターンにまとめられるよ。
(1) 利用する関係なら、インターフェースを境界にして、利用する側はインターフェースのみ使い、利用される側はインターフェースを実装してそれのみ公開しましょう。
そうすれば両者を疎結合にできますよ。
(2) 機能や動作に共通事項があるなら、それをインターフェースして、各型で実装しましょう。
そうすればそのインターフェース抽象型を用いた共通コードにできますよ。
もちろん(1)(2)は部分的に重なっているからね。
さらに高階関数を引数に取るものもこのインターフェース抽象型パターンは使われているね。
高階関数とは両立する話だよ。
(1) 利用する関係なら、インターフェースを境界にして、利用する側はインターフェースのみ使い、利用される側はインターフェースを実装してそれのみ公開しましょう。
そうすれば両者を疎結合にできますよ。
(2) 機能や動作に共通事項があるなら、それをインターフェースして、各型で実装しましょう。
そうすればそのインターフェース抽象型を用いた共通コードにできますよ。
もちろん(1)(2)は部分的に重なっているからね。
さらに高階関数を引数に取るものもこのインターフェース抽象型パターンは使われているね。
高階関数とは両立する話だよ。
224デフォルトの名無しさん
2026/08/16(日) 15:02:31.66ID:Ody7f1dX Fizz buzzって知らなかってけど、wikipediaでルールを読んでみると曖昧で、
いくつかの解釈ができてしまう。
英語版と日本語版では異なる解釈もできる。
だめな仕様書の例ですね笑(jokeですからね念のため)。
オブジェクト(指向)を使うという限定で、extends/interfaceなどを使って書いてみるのはたしかにおもしろい。
いくつかの解釈ができてしまう。
英語版と日本語版では異なる解釈もできる。
だめな仕様書の例ですね笑(jokeですからね念のため)。
オブジェクト(指向)を使うという限定で、extends/interfaceなどを使って書いてみるのはたしかにおもしろい。
225デフォルトの名無しさん
2026/08/16(日) 15:24:35.35ID:4EyRDcWH 別にインターフェースである必要すらなくて
1. 利用する関係なら利用側が必要とするものだけを依存関係の境界にして 利用側は相手の具体的な実装詳細に依存しないようにする
2. 機能や動作に共通事項があるならそれを共通の抽象として切り出す
かな?
Rustにあわせてインターフェースを抽象的な契約と言い換えてもいいけどZigだと必要な操作を満たす型をcomptimeで決めれば済むからねえ
Rustに合わせてインターフェースを抽象的な契約と言い換えてもいいけど Zigだと抽象的な契約を用意せずに利用側が必要とする操作をcomptimeで要求して具体型がそれを満たすことをコンパイル時に検証すれば済むからね C++のテンプレートの考え方と似てる
1. 利用する関係なら利用側が必要とするものだけを依存関係の境界にして 利用側は相手の具体的な実装詳細に依存しないようにする
2. 機能や動作に共通事項があるならそれを共通の抽象として切り出す
かな?
Rustにあわせてインターフェースを抽象的な契約と言い換えてもいいけどZigだと必要な操作を満たす型をcomptimeで決めれば済むからねえ
Rustに合わせてインターフェースを抽象的な契約と言い換えてもいいけど Zigだと抽象的な契約を用意せずに利用側が必要とする操作をcomptimeで要求して具体型がそれを満たすことをコンパイル時に検証すれば済むからね C++のテンプレートの考え方と似てる
226デフォルトの名無しさん
2026/08/16(日) 15:28:09.68ID:4EyRDcWH Zigよ もっと流行れ
227デフォルトの名無しさん
2026/08/16(日) 16:10:14.50ID:7OiFm8W8 >>225
Zigはインターフェースを持たないからむしろ不便で型安全性も低い
インターフェースによる抽象型を使えないからanytype型で扱ってこのように制約することになる
fn printable(comptime T: type) bool {
return @hasDecl(T, "print");
}
fn callPrint(value: anytype) void {
comptime {
if (!printable(@TypeOf(value))) {
@compileError("Type must have a 'print' method");
}
}
value.print();
}
Zigはインターフェースを持たないからむしろ不便で型安全性も低い
インターフェースによる抽象型を使えないからanytype型で扱ってこのように制約することになる
fn printable(comptime T: type) bool {
return @hasDecl(T, "print");
}
fn callPrint(value: anytype) void {
comptime {
if (!printable(@TypeOf(value))) {
@compileError("Type must have a 'print' method");
}
}
value.print();
}
228デフォルトの名無しさん
2026/08/16(日) 16:52:26.67ID:4EyRDcWH >>227
Zigはinterfaceがないから型安全性が低いという指摘は論点がずれてる気がする
不便なのはともかくとしてね
Zigのstatic polymorphismは利用側が要求する操作を満たしているかのほうを何の型なのかよりも重要視してる
comptimeとanytypeで具体的な型がコンパイルで決まるしその型に必要な操作がなかったらコンパイルエラーにちゃんとなる
だから型安全性が低いんじゃなくて名前付きの契約で型を分類制約する仕組みがないというほうが近い
Rustのtrait/interfaceをそのまま使えないのと型安全性が低いのは分けて考えるべき
Zigはinterfaceがないから型安全性が低いという指摘は論点がずれてる気がする
不便なのはともかくとしてね
Zigのstatic polymorphismは利用側が要求する操作を満たしているかのほうを何の型なのかよりも重要視してる
comptimeとanytypeで具体的な型がコンパイルで決まるしその型に必要な操作がなかったらコンパイルエラーにちゃんとなる
だから型安全性が低いんじゃなくて名前付きの契約で型を分類制約する仕組みがないというほうが近い
Rustのtrait/interfaceをそのまま使えないのと型安全性が低いのは分けて考えるべき
229デフォルトの名無しさん
2026/08/16(日) 17:01:36.86ID:bGqhVQCa interfaceで明示した方が可読性も保守性も良い
230デフォルトの名無しさん
2026/08/16(日) 17:19:52.45ID:0pgo/mMd231デフォルトの名無しさん
2026/08/16(日) 17:20:26.30ID:4EyRDcWH >>229
考え方の違いだね
RustやJavaは抽象的な契約を一箇所にまとめることで可読性や保守性を高めるのに対して
Zigは不要な抽象を作らずに実際に必要な操作だけを書くことでコードを単純にするっていう考えだから
考え方の違いだね
RustやJavaは抽象的な契約を一箇所にまとめることで可読性や保守性を高めるのに対して
Zigは不要な抽象を作らずに実際に必要な操作だけを書くことでコードを単純にするっていう考えだから
232デフォルトの名無しさん
2026/08/16(日) 17:26:17.84ID:4EyRDcWH >>230
RustやJavaにあるような抽象的な契約の考えをZigに持ち込むのがそもそもパターンとして間違ってる
RustやJavaにあるような抽象的な契約の考えをZigに持ち込むのがそもそもパターンとして間違ってる
233デフォルトの名無しさん
2026/08/16(日) 17:36:12.25ID:D1LzEAcA >>231
Zigで型をanytypeと書く暇があったら代わりにinterface名を書けばいいよね
そこでのコードの長さは変わらなくてZigは可読性の低下だけ招いてるような
Zigが節約できたのはinterface宣言つまりmethod名と型signatureを列挙することだけかな
可読性の低下と引き換えにZigが得たものが小さすぎて割に合わない気がする
Zigで型をanytypeと書く暇があったら代わりにinterface名を書けばいいよね
そこでのコードの長さは変わらなくてZigは可読性の低下だけ招いてるような
Zigが節約できたのはinterface宣言つまりmethod名と型signatureを列挙することだけかな
可読性の低下と引き換えにZigが得たものが小さすぎて割に合わない気がする
234デフォルトの名無しさん
2026/08/16(日) 18:50:20.61ID:4EyRDcWH235デフォルトの名無しさん
2026/08/16(日) 19:37:14.99ID:uznes1x1 Zig方式だと異なるインターフェース相当の同一型メソッドを区別できずに混ざってしまうため型安全性も落ちる
236デフォルトの名無しさん
2026/08/16(日) 21:15:59.83ID:8yz0P3zw ・構造的型付けは性質の一致をみる
・名前的型付けは概念(性質の集合)の一致をみる
ものだとすると、構造的型付けの方がロジックバグを作りやすいのはそのとおりだと思う
型安全という概念はプログラムの実行時に未定義の操作(存在しないメソッドの呼び出しなど)を起こさないというものなのでどちらも型安全ではあるってことなんじゃないかな
・名前的型付けは概念(性質の集合)の一致をみる
ものだとすると、構造的型付けの方がロジックバグを作りやすいのはそのとおりだと思う
型安全という概念はプログラムの実行時に未定義の操作(存在しないメソッドの呼び出しなど)を起こさないというものなのでどちらも型安全ではあるってことなんじゃないかな
237デフォルトの名無しさん
2026/08/16(日) 21:32:38.32ID:8yz0P3zw 型安全じゃないなら何と表現するのが良いのかな、意図安全?
238デフォルトの名無しさん
2026/08/16(日) 21:38:31.47ID:3V/Fi6zs Zigはそのanytypeの時に複数の異なる型がやって来るわけだけど
生成コードは単相化?それとも動的ディスパッチ?
生成コードは単相化?それとも動的ディスパッチ?
239デフォルトの名無しさん
2026/08/16(日) 22:34:55.59ID:Co7DsicL Zigとかどうでもよくね
思想が他と違うだろあれ
思想が他と違うだろあれ
240デフォルトの名無しさん
2026/08/16(日) 22:37:18.88ID:SoMBue1h241デフォルトの名無しさん
2026/08/16(日) 23:34:48.38ID:4RZhk79G それ起きるのなぜかfinalがないRustだけだろ
242デフォルトの名無しさん
2026/08/17(月) 00:16:26.92ID:38V+3mdM そもそもRustでは起きない
243デフォルトの名無しさん
2026/08/17(月) 00:19:02.71ID:O4jJSPJp >>242
どうしてそう考えるの?
どうしてそう考えるの?
244デフォルトの名無しさん
2026/08/17(月) 09:45:51.74ID:UewEXcwQ245デフォルトの名無しさん
2026/08/17(月) 12:16:16.38ID:CJr3tgZ2 論破されても同じ主張を根拠無く延々と繰り返す
それが複おじ!!
それが複おじ!!
246デフォルトの名無しさん
2026/08/17(月) 13:29:22.69ID:wAb5rDbA で、お前ら実際にクラス継承なんか使ってんのか?
247デフォルトの名無しさん
2026/08/17(月) 13:37:49.96ID:GxsMwSQY なるべく使わないがそれが何か
248デフォルトの名無しさん
2026/08/17(月) 14:03:56.79ID:rUdNNfGv 必要がない機能がないなら用足りないっつってもいいが
使いもしない機能が余計についてるだけのことでとやかく語って何が楽しいの?
使いもしない機能が余計についてるだけのことでとやかく語って何が楽しいの?
249デフォルトの名無しさん
2026/08/17(月) 14:12:17.93ID:9dsT8/CZ >>248
お前のその斜に構えた態度がクソダセーって話でお前がいないところでみんな盛り上がってるから心配すんな楽しいぞ
お前のその斜に構えた態度がクソダセーって話でお前がいないところでみんな盛り上がってるから心配すんな楽しいぞ
250デフォルトの名無しさん
2026/08/17(月) 14:13:30.75ID:rUdNNfGv 時間の無駄
251デフォルトの名無しさん
2026/08/17(月) 14:20:40.34ID:9dsT8/CZ 5ch見て時間の無駄は草
252デフォルトの名無しさん
2026/08/17(月) 14:58:45.13ID:GxsMwSQY >>249
それどこよ?
それどこよ?
■ このスレッドは過去ログ倉庫に格納されています
ニュース
- なぜコンビニは「外国人店員」だらけになったのか? 大手3社で8万人超…元セブン社員が明かす「日本人が集まらなくなった」現場の実情★2 [♪♪♪★]
- 大谷翔平が吐露…「自分のなかでもあまりよくない年の一つ」「WBCがあるとすごく長く感じる」 [王子★]
- 【沖縄】「許せない」「基地を返せ」 強盗殺人事件、沖縄に怒りの声 [ぐれ★]
- 【平均給与】男性は400万円台、女性は200万円台が最多。平均487万円より下に人が集まり、年収500万円以下が約6割 [首都圏の虎★]
- 【STARTO】キンプリ髙橋海人〝ソロ名義〟既存ボーカロイド「KAITO」と丸カブり「普通気にしない?」ボカロファン嘆き [Ailuropoda melanoleuca★]
- 夫婦の性行為は義務なのか 「したくない」と言ったら?法学者の見解 [おっさん友の会★]
- 【実況】博衣こよりのえちえちみんなでBBQ🧪★2
- 【実況】博衣こよりのえちえちみんなでBBQ🧪★3
- 🏡ブフダイン❄
- ガールズ&パンツァー最終章4話、実況🏡21時スタートなのらよ🍬
- 












👊😅👊



- jcコテきた