Go における脆弱な基本クラスの問題: 継承よりも構成が多いにもかかわらず
脆弱な基本クラスの問題は、基本クラスへの変更により予期せぬ事態が発生する可能性がある場合に発生します。派生クラスでの動作。この問題は一般に、派生クラスが基本クラスのメソッドとフィールドを継承する継承に起因すると考えられます。
Go では、継承は実装されていません。代わりに、Go は合成を使用し、構造体に他の構造体のインスタンスを含めることができます。ただし、埋め込み型を使用する場合、基本クラスの脆弱性の問題が Go に依然として存在する可能性があると主張する人もいます。
埋め込み型は、埋め込み型のフィールドとメソッドをラッパー型に昇格させます。これによりアクセスが便利になりますが、ポリモーフィズムが排除されます。これは、埋め込み型で定義されたメソッドをラッパー型でオーバーライドできず、埋め込み型によって行われるメソッド呼び出しは常に元の定義を呼び出すことを意味します。
その結果、脆弱な基本クラスの問題が存在します。 Go では緩和された形で。埋め込み型のメソッドまたはフィールドへの変更は、ラッパー型に影響を与える可能性がありますが、これはラッパー型が同じ名前の独自のメソッドを定義していない場合に限られます。
例
次の Java コードを考えてみましょう。このコードでは、基本クラス Counter に増分メソッド inc() と増分メソッド incBy() が含まれています。派生クラス MyCounter は、inc() をオーバーライドして incBy(1) を呼び出します。
<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>
基本クラスの incBy() メソッドがループを使用するように変更されると、派生クラス MyCounter は無限ループに入ります。 inc() は、再度 inc() を呼び出す incBy() を呼び出すためです:
<code class="java">void incBy(int n) { for (; n > 0; n--) { inc(); } }</code>
Go では、埋め込み型のメソッドのオーバーライドをサポートしていないため、同じ例ではこの問題は発生しません:
<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() という名前のメソッドを定義していないため、この動作を継承しません。代わりに、Counter 型で定義された元の inc() メソッドを呼び出します。
したがって、埋め込み型にはポリモーフィズムがないため、Go では脆弱な基本クラスの問題は大きな懸念事項ではなく、予期しない動作が防止されます。埋め込み型を変更するとき。
以上がGo の構成モデルは依然として脆弱な基本クラスの問題に悩まされる可能性がありますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。