つまり、child.update()が呼び出された場合、派生クラスのインスタンスは、以前にすべてのスーパークラスのupdate()を暗黙的に呼び出す必要がありますか?
4 に答える
それは本当にスーパークラス/ベースクラス関数が何をするかに依存します。最初に呼ぶこともあれば、最後に呼ぶこともあります。条件付きで呼ぶこともあれば、まったく呼ばないこともあります。
多くの場合(これはC#のバックグラウンドから来ています)、基本クラス関数はイベントを発生させるだけであり、子クラスはそのメソッドをオーバーライドしてイベントのような機能を取得します。子供がそのイベントの発生を望まない場合があります。
class Base {
public event EventHandler UnhandledError;
protected virtual void OnUnhandledError(Error error) {
if (UnhandledError != null)
UnhandledError(this, EventArgs.Empty);
}
}
class Derived : Base {
protected override void OnUnhandledError(Error error) {
if (HandleError(error))
return; // We took care of it. Don't raise the event.
// We couldn't handle it. Let the base class raise the event.
base.OnUnhandledError(error);
}
}
いいえ。誰かがupdate()をオーバーライドする必要があり、親からの呼び出しを完全に防止したい場合があります。その場合、暗黙の呼び出しではパフォーマンスが低下するだけでなく、望ましくないことも行われる可能性があります。
クラスを別のクラスにラップするのではなく、スーパークラスから継承します。
super.method()
親の動作を拡張する必要がある場合にのみ呼び出す必要があるスーパークラスメソッドをオーバーライドしますmethod()
。
(私が知っている言語では)良い答えはありません。スーパーメソッドを置き換えたい場合があります。実行前に何かを挿入したい場合もあれば、実行後に何かを挿入したい場合もあります。拡張クラスは、オーバーライドするクラスの詳細について、必要以上に知る必要があるようです。(これはクローズドソースシステムでは厄介になります。)また、基本クラスは、呼び出し元のクラスの動作を制御して、スーパーメソッドを強制的に呼び出させたい場合もありますが、これも正しくありません。最良のことは、スーパークラスがオーバーライド可能なメソッドを可能な限り文書化して、オーバーライドするプログラマーが何をすべきかを推測できるようにすることだと思います。
これを適切かつ正しく処理するために私が最も近づいたのは、オーバーライドできないようにターゲットメソッドを作成してから、オーバーライドできる以外に何もしない1つまたは複数のメソッドを呼び出すようにすることです。次に、オーバーライドするクラスは、スーパークラスを損なうことなく、関心のあるメソッドをオーバーライドできます。
究極のプログラミング言語には、この問題に対する絶対確実な解決策があります。