Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
0
Help us understand the problem. What is going on with this article?
@c-cho

ポリモーフィズムクイズ

More than 3 years have passed since last update.

Java Puzzlers Advent Calendar 2016の投稿は一つだけ足りないという惜しい状況になっていますので、Day 5の記事を代打させて頂きます。

問題

class MyTest
{
    private static class A {
        String message = "hello";
        Consumer<String> hello = s -> System.out.print(message + s);
        void hello(String s) { this.hello.accept(s); }
    }

    private static class B extends A {
        String message = "ハロー";
        void hello(String s) { this.hello.accept(s); }
    }

    public static void main(String[] args) {
        A b = (A) new B();
        b.hello(" world");
        System.out.print("/");
        b.hello.accept(" world");
    }
}

上記のコードの実行結果は

  • A. ハロー world/hello world
  • B. ハロー world/ハロー world
  • C. hello world/ハロー world
  • D. hello world/hello world
  • E. コンパイルエラー

正解

答えは

  • D. hello world/hello world

説明

一見複雑そうですが、実はポリモーフィズムをちゃんと理解できれば、すぐ解けるはずです。それでは、mainメソッドの処理を追って見ましょう。

- mainメソッドの一行目ではAB実装の変数bを宣言しました。(A)というアップキャストの処理が書かれていますが、実はコンパイラが自動的に行ってくれる作業なので、ただの目障りで意味がありません(勿論エラーにもなりませんが・・)。
- bのメソッドを利用する際に、コンパイラはまず実装型にそのメソッドがあるかどうかを見ます(二行目)。クラスBhelloというメソッドがありましたね。オーバーライドが明記されていませんが、シグネチャに違いがない為、親クラスのhelloメソッドがオーバーライドされていることは分かります。ポリモーフィズムのルールによりクラスBhelloメソッドが実行されます。
- helloいうメソッドはhelloというコンシューマー関数のフィールドを呼んでいますが、残念ながらAクラスにしかhelloが存在しません。その為、やむを得ずAクラス内のhello関数を利用することになります。(ちなみに、メソッド名とフィールド名の重複は許されますので、コンパイルエラーになりません)
- helloという関数はmessageというフィールドを使います。クラスAmessagehelloですので、出力結果はhello worldになります。クラスBにもmessageというフィールドが存在しますが、今使っているhello関数とは無関係ですね。
- さらにmainの四行目ですが、bオブジェクトのhello関数を利用しているように見えますね。しかし、フィールド変数のオーバーライドが存在しないことを忘れてはいけません。hello関数はhelloメソッドと同じく処理手続きを定義するものですが、本質的にはmessageのようなフィールド変数です。その為、どのフィールドが利用されるかは宣言時の参照型によります。Aとして宣言された為、クラスAhello関数が利用され、二行目の出力結果と同じようになります。

参考

0
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
c-cho

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
0
Help us understand the problem. What is going on with this article?