オーバーライドとオーバーロードの構文上の違いは知っています。また、オーバーライドは実行時のポリモーフィズムであり、オーバーロードはコンパイル時のポリモーフィズムであることも知っています。しかし、私の質問は次のとおりです。「オーバーロードは本当にコンパイル時のポリモーフィズムですか?メソッド呼び出しは本当にコンパイル時に解決しますか?」. 私の主張を明確にするために、クラスの例を考えてみましょう。
public class Greeter {
public void greetMe() {
System.out.println("Hello");
}
public void greetMe(String name) {
System.out.println("Hello " + name);
}
public void wishLuck() {
System.out.println("Good Luck");
}
}
すべてのメソッドgreetMe(), greetMe(String name), wishLuck()
が公開されているため、すべてオーバーライドできます (オーバーロードされたものを含む)。例えば、
public class FancyGreeter extends Greeter {
public void greetMe() {
System.out.println("***********");
System.out.println("* Hello *");
System.out.println("***********");
}
}
ここで、次のスニペットを検討してください。
Greeter greeter = GreeterFactory.getRandomGreeter();
greeter.greetMe();
このgetRandomGreeter()
メソッドはランダムGreeter
オブジェクトを返します。のオブジェクト、または のようなそのサブクラスのいずれかを返すことができGreeter
ます。クラスファイルを使用するか動的にロードしてオブジェクトを作成し、リフレクション(リフレクションで可能だと思います)またはその他の可能な方法を使用してオブジェクトを作成します。これらのメソッドはすべて、サブクラスでオーバーライドされる場合とされない場合があります。そのため、コンパイラは特定のメソッド (オーバーロードされているかどうか) がオーバーライドされているかどうかを知る方法がありません。右?また、ウィキペディアは仮想機能について次のように述べています。FancyGreeter
GraphicalGreeter
getRandomGreeter()
new
Greeter
Java では、すべての非静的メソッドはデフォルトで「仮想関数」です。オーバーライドできないキーワード final でマークされたメソッドと、継承されないプライベート メソッドのみが非仮想です。
仮想関数は動的メソッド ディスパッチを使用して実行時に解決され、すべての非プライベート、非最終メソッドは (オーバーロードされているかどうかにかかわらず) 仮想であるため、実行時に解決する必要があります。右?
では、コンパイル時にオーバーロードを解決するにはどうすればよいでしょうか? または、私が誤解していること、または見逃していることはありますか?