オーバーロードされたメソッドは、メソッドを呼び出す参照タイプに基づいてコンパイル時に決定されますが、オーバーライドされたメソッドは、メソッドを呼び出す参照の実際のオブジェクトタイプによって決定されることを知っています。問題は、ポリモーフィズムがオーバーライドのみであり、オーバーロードではない理由です。
4 に答える
Javaでのポリモーフィズムを可能にする実装メカニズムは、最初の引数の実行時型に基づいたメソッドの動的ディスパッチです(呼び出しa.method(b, c)
でa
は、メソッドの最初の引数と見なすことができます)。したがって、Javaは単一ディスパッチOOP言語です。結果として、他のすべての引数はこのメカニズムに関与せず、それらの型はコンパイル時に静的に決定されます。たとえば、
class MyObject {
public boolean equals(MyObject o) { ... }
}
その後
MyObject m1 = new MyObject();
Object o = new MyObject();
System.out.println(m1.equals(o));
true
メソッドが呼び出されていないため、印刷できません。コンパイラーは呼び出しMyObject.equals(Object)
を認識し、継承されたメソッドの呼び出しとしてコンパイルしましたObject.equals(Object)
。ランタイムメソッドディスパッチメカニズムはequals(Object)
、呼び出すオーバーライドメソッドのみを決定します。
ポリモーフィズムとは、名前が示すように、「同じ形式の」メソッドが異なるコンテキストで異なる動作を示す場合です。「同じフォーム」という用語は、「同じ署名」を意味します。これは、ポリモーフィズムをオーバーロードされたメソッドと関連付けることができないことを意味します。なぜなら、それらにはそもそも「異なる形式」があるからです。これについて考える別の方法は、ポリモーフィズムの動作を確認するには型とサブタイプが必要であるということです。オーバーロードされたメソッドは、単一のクラスのコンテキストで定義されます。
これは技術的な理由によるものです。通常this
、メソッドの非表示の最初のパラメーターとしてポインターのみが実行時に分析され、呼び出されるメソッドが決定されます。
他のパラメータも分析される場合、それは複数のディスパッチと呼ばれます。複数のディスパッチをネイティブでサポートする言語がいくつかあります。
あなたはこれについて混乱しています。同じクラス (階層ではない)
Overloading
で、同じ名前でシグネチャーが異なるメソッドの 1 つを選択することを指します。親クラスに継承されたメソッドのうち、実行時の型に応じて同名のメソッドが選択されます。
同じ名前と署名のメソッドを持つ基本クラスと派生クラスがある場合、これは実行時に正しいものと判断されます。
Overriding
overriding
コンパイラは、同じクラスoverloading
で利用可能なメソッドの中から、使用するメソッドの正しいバージョンを選択します。
ランタイム タイプを見つける必要はありません。コンパイラはコンパイル時にこれを把握できます