質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.65%

コードの一部が何をしているかわかりません。

解決済

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 665

 FooService service = (FooService) obj;

参考書に描いてあるinstanceof演算子の勉強中にこの処理は何をしているのだろうと思い質問しました。
上記のコードの横の説明にはobjはFooServiceであるため、キャストが可能と書いてありました。

あと、 Object obj = new FooService("hello");
の部分で Objectクラスのことを調べたのですが、イマイチ理解できなかったのでその説明もあるとありがたいです。

 理解できないコード

FooService service = (FooService) obj;

 該当のソースコード

public class FooService extends AbstractBaseService {

    public FooService(String name) {
        super(name);
    }

    @Override
    public String say() {
        return "Hello";
    }

}
public interface BaseService {

    public String say();

}
public abstract class AbstractBaseService implements BaseService {

    protected String name;

    public AbstractBaseService(String name) {
        this.name = name; 
    }

}
public class Tryout {
    public static void main(String...args) {

        Object obj = new FooService("hello");

        System.out.println(obj instanceof FooService);
        System.out.println(obj instanceof AbstractBaseService);
        System.out.println(obj instanceof BaseService);
        System.out.println(obj instanceof Integer);
        System.out.println(obj instanceof FooService);

        if(obj instanceof FooService) {
            FooService service = (FooService) obj;// ここがわかりません。
            System.out.println(service.say());
        }
    }

}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+1

あらゆる参照型はObjectクラスを継承します。そのため、あらゆる参照型オブジェクトは、Object型オブジェクトとして扱えます。

…と、こう言ってもわけがわからないだろうと思いますので、身近な例えで説明します。

身の回りには様々なモノがあります。パソコン、スマホなどといった電化製品、本、手帳などの紙製品、犬、猫などの動物。
用途や特徴は様々ありますが、「物体」という意味合いにおいての「モノ」であるという点で、すべて同列に扱えます(倫理的な問題はさておいて)。
なので、「何かモノ持ってきて」とでも言われた場合、上記に挙げたものをなんでも持っていけるのです。これが、「あらゆる参照型オブジェクトは、Object型オブジェクトとして扱える」ということの意味です。これに限らず、あるオブジェクトをそれより大きな括りの型として扱う場合は、断りなく入れることができます(パソコンを電化製品として扱うぶんには何も問題ない)。これをアップキャストと呼んだりします。

さて、モノとして扱いを統一しましたが、場合によってはモノとして扱ったオブジェクトを、例えばパソコンとして扱いたいと言うような場面が出てくるかもしれません。モノとして扱う以上、それが電化製品ではない可能性もあるため、例えば「電源を入れる」という操作ができる保証がないのです。
しかし、あらゆるオブジェクトがモノとして扱える以上、モノとして扱っているそのオブジェクトがパソコンとして扱えるかは不確定です。
そのため、どうしても扱いたい場合には断りを入れてくださいとJavaは要求しているのです。その断りこそ、objの前に付いている(FooService)なのです。このように、オブジェクトをより小さな括りとして扱う場合に行うのがダウンキャストと呼ばれる操作です。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/03/07 01:32

    わかりやすく教えていただき本当にありがとうございます。

    ・・・
    正直最初は全く理解できませんでした。
    アップキャストとダウンキャストを理解するのに、ほぼ最初から参考書やサイト、他の質問の返答をもう一度見直した上で読むと本当にわかりやすかったです。

    キャンセル

  • 2018/03/07 09:26

    ちょっと横から失礼します。
    今回の件とは、関係のない話ですが。

    >ほぼ最初から参考書やサイト、他の質問の返答をもう一度見直した上で読むと本当にわかりやすかったです。
    参考書のようなものは、「理解できる相性」のようなものがあるので、私はいつも、書籍を2〜3冊買って学習することをお勧めしています。1冊だけではわからなかったことが別の本を読んだらわかるということは、しばしばあることですので。

    キャンセル

  • 2018/03/07 15:50

    参考書のようなものをもう一冊買ってみますね。

    キャンセル

+1

何をしているのか

型キャストには、アップキャストダウンキャストがあります。
継承関係はA is-a Bという関係で、この場合ObjectがBに当たります。

  • アップキャスト: AからBへのキャスト
    Object obj = new FooService("hello");
  • ダウンキャスト: BからAへのキャスト
    FooService service = (FooService) obj;

アップキャストは暗黙に行えるのですが、対してダウンキャストは型を明示しないといけません。
Qiita - なぜアップキャストは安全で、ダウンキャストは危険なのか

なぜダウンキャストが必要か

この部分がミソです。

System.out.println(service.say());

sayはFooServiceのメソッドであって、Objectのメソッドではないからです。
キャストしなかったときにどのようなコンパイルエラーが生じるのか観察してみると良いでしょう。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/03/07 15:44

    なるほど、あまり使わないのですね。
    返信ありがとうございます。
    詳しくっていうのは、
    ”ダウンキャストは覗いてはいけないメモリ空間を覗けるので危険がある”
    ってのをコード付きで説明してくれているって意味です。

    キャンセル

  • 2018/03/07 16:00

    例えば次のようなコードもコンパイルが通ってしまいます。
    ---
    Object obj = new String("hoge");
    ((FooService))obj.say(); // objはFooService「かもしれない」からコンパイルは通る

    実行時に例外ClassCastExceptionで落ちますが、本来ならコンパイル時に気付けるはずの型の不整合に実行時まで気付けないのは大きなデメリットであり、開発を阻害するリスクです。
    実際にこの例外を潜り抜けてメモリを覗く方法があるかどうかはちょっとわかりません。

    キャンセル

  • 2018/03/07 16:53

    なるほど、返信ありがとうございます!
    よく返信していただき本当に毎回助かります。
    自分もいつか回答できるレベルまで到達できるように頑張ります。

    キャンセル

+1

objはObject型であるため、say()というメソッドは存在しません。

say()というメソッド実行するために、このメソッドを持つFooService型に直しています。

この例文は、機能の確認のためのものなので、必要性が理解出来ないかもしれません。

もう少し学習を進めてみて、まだわからないようなら、再度質問してみるのがいいかと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/03/07 01:34

    返答ありがとうございます。
    確かに、今はあまり必要性を感じませんね。
    そのうち必要になるだろうという時はいつになるでしょうか?

    キャンセル

  • 2018/03/07 09:17

    >そのうち必要になるだろうという時はいつになるでしょうか?

    うーん、いつと言われても、「必要になった時」としか。。。

    キャストについては、

    ・オブジェクト指向型言語(当然javaも含む)では必須の多態性というもので必須技術のため、少なくてもアップキャストに関しては、そのうち嫌でも経験する

    ・その時になれば、色々なことに慣れて理解が速いと推測

    ・ダウンキャストに関しては、
    「いいサンプルがパッと浮かばなかった」
     → 「ということはそれほど重要ではない」
     → 「ということは先送りしても問題ない」
     → 「将来、どうしても使わないければならない状況になったときでも、ダウンキャストだけしらないのはあり得ないし、その頃には詳細を自分で調べることができるようになっているはず」

    ・使わない技術は、どうせ詳細は覚えていられないし、何となく頭の片隅にさえあれば、先送りしても問題ない

    という考えがありました。


    といった感じです。

    キャンセル

  • 2018/03/07 15:46

    なるほど、返答ありがとうございます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.65%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る