こんにちは
村上です。
たぶん今年最後のJavaネタです。
オーバーライドとオーバーロードの違いって知ってますか?
そんなの当然!!
って声が聞こえてきそうですね。
とりあえずおさらい
オーバーライド
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
class Parent { public void hoge() { System.out.println("Parent"); } } class Child1 extends Parent { @Override public void hoge() { System.out.println("Child1"); } } class Child2 extends Parent { @Override public void hoge() { System.out.println("Child2"); } } |
ってクラスがあった時に下記の実行結果は
1 2 3 4 5 6 7 8 |
Parent p = new Parent(); p.hoge(); // 「Parent」と出力 Parent c1 = new Child1(); c1.hoge(); // 「Child1」と出力 Parent c2 = new Child2(); c2.hoge(); // 「Child2」と出力 |
ですね。
つまり、ParentクラスのhogeメソッドはChild1、Child2クラスで上書きされるっていうことです。
ここには継承やら多態性やらオブジェクト指向的なことが発生してこうなるんですが、そこら辺は深くは触れないです。
オーバーロード
次にオーバーロードです。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public void foo(Parent p) { System.out.print("Call Parent => "); p.hoge(); } public void foo(Child1 c1) { System.out.print("Call Child1 => "); c1.hoge(); } public void foo(Child2 c2) { System.out.print("Call Child2 => "); c2.hoge(); } |
というメソッドがあるとき下記の実行結果は
1 2 3 4 5 6 7 8 |
Parent p = new Parent(); foo(p); // 「Call Parent => Parent」と出力 Child1 c1 = new Child1(); foo(c1); // 「Call Child1 => Child1」と出力 Child2 c2 = new Child2(); foo(c2); // 「Call Child2 => Child2」と出力 |
ですね。
ようするにfooメソッドの引数が異なれば多重定義できるということです。
この実行結果は?
では次の実行結果はどうなるでしょうか?
1 2 3 4 5 |
Parent cp1 = new Child1(); foo(cp1); Parent cp2 = new Child2(); foo(cp2); |
オーバーライドとオーバーロードの混合技です。
cp1、cp2のオブジェクトの実態はChild1、Child2です。そして、多態性を利用してParentで宣言されてます。
fooメソッドは引数がParent、Child1、Child2で多重定義されています。
何が出力されるでしょうか?
実行結果は
1 2 3 4 5 |
Parent cp1 = new Child1(); foo(cp1); // Call Parent => Child1 Parent cp2 = new Child2(); foo(cp2); // Call Parent => Child2 |
結果も混合ですね。
オーバーロード側はオブジェクトはParentと認識され、オーバーライド側はChild1、Child2と認識されています。
これはどういうことかというと、オーバーロードはコンパイル時にメソッド呼び出しが決まり、オーバーライドは実行時にメソッド呼び出しが決まるからです。
cp1もcp2も宣言はParentなので、オーバーロードはfooの引数がParentのメソッドが呼ばれます。
また、実行時つまり実態はChild1およびChild2になるので、オーバーライドはそれぞれオーバーライドされたメソッドが呼ばれています。
まとめ
とくにまとめることは無いですが、昔このコードを書いて思った実行結果にならないので、調べた内容です。
まぁ、テストすれば思った動きをしないので発見されずに不具合に至ることは多分ないですが、なぜかわからずハマることがあります。
Javaのちょっとした雑学ということで、現場のプログラマの人に聞いてみて下さい。
みなさん意外と知らないと思います。