抽象的ではないがオーバーライドしなければならないメソッドを作成する方法はありますか?
-
27-10-2019 - |
質問
子クラスにスーパークラスの非抽象メソッドをオーバーライドさせる方法はありますか?
親クラスのインスタンスを作成できる必要がありますが、クラスがこのクラスを拡張する場合は、いくつかのメソッドの独自の定義を提供する必要があります。
解決
私が知る限り、これを行うための直接的なコンパイラ強制の方法はありません。
親クラスをインスタンス化可能にしないで 回避できますが、代わりに、デフォルトの実装を持ついくつかの(プライベートの可能性がある)サブクラスのインスタンスを作成するファクトリメソッドを提供します。 ジェネラコディセタグプレ
現在、new Base()
を書くことはできませんが、Base.create()
を実行してデフォルトの実装を取得することはできます。
他のヒント
他の人が指摘しているように、これを直接行うことはできません。
ただし、これを行う1つの方法は、次のように戦略パターンを使用することです。 ジェネラコディセタグプレ
この方法でインターフェースを作成することを検討してください。クラスの子孫はそれを実装する必要があります。
最も簡単な方法は、基本クラスから継承する抽象クラスを作成することだと思います。 ジェネラコディセタグプレ
いいえ、それが抽象メソッドの要点です。あなたのユースケースは何ですか?おそらく、根本的なニーズに基づいて考えることができます。
これはどうですか:メソッドのデフォルトの実装内で、リフレクションを使用してオブジェクトの正確なクラスを取得します。クラスが基本クラスと完全に一致しない場合は、RuntimeExceptionまたは同等のものをスローします。 ジェネラコディセタグプレ
それが不可能な理由があります!
派生クラスは、メソッドをオーバーライドするときに、基本クラスの実装を呼び出すだけです。
では、クラスにメソッドをオーバーライドさせることのポイントは何ですか?メリットはないと思います。
答えはノーです。テンプレートデザインパターンを使用して再設計できます。それはあなたを助けるかもしれません。
または、子クラスにインターフェースを実装させることもできます。インターフェイスは、スーパークラスによって実装される場合とされない場合があります。
基本クラスに例外をスローするメソッドをいつでも含めることができます。
技術的には基本クラスでメソッドが定義されていますが、メソッドをオーバーライドしないと使用できません。このような場合、明示的なthrowsステートメントを必要としないため、ランタイム例外を優先します。次に例を示します ジェネラコディセタグプレ
欠点は、これがBase
オブジェクトの作成を妨げないことです。ただし、「オーバーライドする必要がある」メソッドの1つを使用しようとすると、すぐにクラスをオーバーライドする必要があることがわかります。
このソリューションはリクエストの説明を十分に満たしていますが、アプリケーションはおそらくこのようなソリューションを必要としないことでメリットがあります。abstractキーワードが提供するコンパイラチェックでランタイムクラッシュを回避する方がはるかに優れています。
他の答えを反映し、派生クラスに非抽象メソッドをオーバーライドさせるコンパイラ強制の方法はないと言います。メソッドを抽象化することの全体的なポイントは、このシグネチャを持つメソッドが存在する必要があるが、基本レベルでは指定できないため、派生レベルで指定する必要があることを定義することです。基本レベルでメソッドの機能する、重要な実装(空ではなく、例外をスローしたりメッセージを表示したりしないなど)がある場合、これは、を呼び出すために厳密に必要なわけではありません。派生クラスのコンシューマーからのメソッドが成功します。したがって、コンパイラーは、基本レベルまたは派生レベルのいずれかで非常に正常に実行できるメソッドのオーバーライドを強制する必要はありません。
派生クラスで作業中の実装をオーバーライドする必要がある状況では、基本実装が派生クラスのコンシューマーが望むことを実行しないことは明らかです。基本クラスに十分な実装がないか、間違った実装があります。そのような場合、クラスから派生したプログラマーが自分のしていることを知っていることを信頼する必要があります。したがって、新しいオブジェクトを使用するコンテキストでは正しい答えが得られないため、メソッドをオーバーライドする必要があることを知っています。
あなたにできることが1つ考えられます。封印された(Javaheadsの最終的な)「デフォルト」実装を備えた抽象的なベースが必要になります。このように、「基本」クラスであるかのようにすぐに使用できるメソッドの基本的な実装がありますが、新しいシナリオ用に別のクラスを定義するには、抽象クラスに戻って、したがって、メソッドを再実装する必要があります。このメソッドは、クラス上で唯一の抽象的なものである可能性があるため、他のメソッドの基本的な実装を利用することができます。 ジェネラコディセタグプレ
ただし、これには2つの欠点があります。まず、継承を通じてDefaultClassの実装にアクセスできないため、DefaultClassの実装を拡張することはできません。つまり、DefaultClassが行うことを実行するには、さらにもう少し、DRYに違反してDefaultClassからコードを書き直す必要があります。次に、DerivedClassからの継承を許可している場合はオーバーライドを強制できないため、これは1レベルの継承に対してのみ機能します。
これは役立つかもしれません: ジェネラコディセタグプレ
わかりました、この方法で学びましょう。私はJavaスタイルのガイドラインに従い、Java構文を使用しています。したがって、多重継承およびC ++テンプレートは使用できないと想定されます。
親クラスのメソッドを抽象化することは必須ではありません。 OOPでは、ポリモーフィズムの概念を使用します。同じ方法を2つ以上の異なる方法で使用できます。 これはメソッドのオーバーライドと呼ばれます。
例を見てみましょう。 ジェネラコディセタグプレ
これは「meowww !!!」を出力します画面上。
ただし、これは、メソッドmakeSoundを子クラスでオーバーライドする必要があることを意味するものではありません。
子クラスにメソッドのオーバーライドを強制する必要がある場合は、クラスごとにインターフェースを実装することをお勧めします。 ジェネラコディセタグプレ
これは「meowwww !!!」も出力します画面上
推奨されない場合もありますが、メソッドの実装で例外(MethodeMustBeOverRiddenExpなど)をスローできます。 もちろん、これはランタイム強制ですが、何もしないよりはましかもしれません。