Go における脆弱な基本クラスの問題: 微妙な違い
設計原則として継承よりも合成を採用しているにもかかわらず、疑問は残ります。 Go には脆弱な基本クラスの問題が存在しますか?
脆弱な基本クラスの問題の定義
脆弱な基本クラスの問題は、基本クラスの変更がその派生クラスに影響を与えるときに発生します。意図しない方法。これは、派生クラスのメソッドが基本クラスのメソッドをオーバーライドできるポリモーフィズムによって発生します。その後、基本クラスのメソッドが変更されると、派生クラスの動作が意図せず破壊される可能性があります。
問題に関する Go の視点
Go では、次の理由によりポリモーフィズムが存在しません。仮想メソッドがないためです。代わりに、Go は埋め込みを利用し、構造体に別の構造体を含めて、そのメソッドに直接アクセスできます。このアプローチでは、脆弱な基底クラスの問題による直接的な影響は排除されますが、微妙なニュアンスが生じます。
埋め込みとメソッドのプロモーション
構造体が埋め込まれると、そのすべてがメソッドは、それを囲んでいる構造体にプロモートされます。ただし、これらのメソッドは、それを囲んでいる構造体でオーバーライドすることはできません。代わりに、同じ名前の新しいメソッドを追加できますが、埋め込み構造体内からプロモートされたメソッドを呼び出すと、元の定義が引き続き呼び出されます。
コンテキスト内の例
脆弱な基本クラスの問題を示す次の Java の例を考えてみましょう:
<code class="java">class Counter { int value; void inc() { value++; } void incBy(int n) { value += n; } } class MyCounter extends Counter { @Override void inc() { incBy(1); } }</code>
ここで、Counter.incBy() を変更して反復して inc() を呼び出すと、MyCounter.inc() が壊れ、無限ループ。
ただし、Go では、ポリモーフィズムがないため、同様の例ではそのような中断は発生しません。埋め込まれた Counter メソッドはオーバーライドできないため、呼び出しコンテキストに関係なく、元の Counter.Inc() メソッドが常に呼び出されます。
<code class="go">type Counter struct { value int } func (c *Counter) Inc() { c.value++ } func (c *Counter) IncBy(n int) { c.value += n } type MyCounter struct { Counter } func (m *MyCounter) Inc() { m.IncBy(1) }</code>
この場合、Counter.IncBy() の変更は影響しません。 MyCounter.Inc() は、カウンタを 1 ずつインクリメントし続けます。
結論
Go では、仮想メソッドがないことによる脆弱な基底クラスの問題が軽減されます。 、完全に排除するわけではありません。埋め込み中のメソッドのプロモーションは、問題の微妙な形式をもたらします。ただし、このニュアンスは、古典的な脆弱な基本クラスの問題と比較すると、混乱が少なく、予測可能です。
以上がGo の埋め込みアプローチは脆弱な基本クラスの問題を解決しますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。