• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:InputStreamのread()関数)

InputStreamのread()関数

このQ&Aのポイント
  • InputStreamのread()関数とは?
  • FilterInputStreamとの関係について
  • Socketを使用したInputStreamの読み取り

質問者が選んだベストアンサー

  • ベストアンサー
  • koko_u_
  • ベストアンサー率18% (459/2509)
回答No.5

>いや、しかし、 >Socketでは >public InputStream getInputStream()throws IOException > > その説明では >public HogeStream getInputStream() > > で無ければならず。 引数の時と同じ理屈です。 getInputStream() は InputStream の何かの派生クラスのインスタンスを「実行時に状況に応じて」戻します。 コードを書く時には、実行時に戻ってくる具体的な型はわからないけれど、 InputStream の派生クラスであることはわかっています。 そのため、InputStream 型の変数 in を宣言して、これで InputStream の派生クラスのオブジェクトを受け取っているのです。 InputStream には read() が仮想関数として宣言されているので、その派生クラスは read() を実装しているはずです。 これによって in.read() に必ず意味があることが保証され、 「実行時に」getInputStream() から戻されたインスタンスが実装している read() が呼び出されます。

その他の回答 (4)

  • aton
  • ベストアンサー率47% (160/334)
回答No.4

koko_u_さん,大変ですね。 質問者というより,このサイトを利用するJava/オブジェクト指向言語学習者のために回答を書きます。 本質的には継承に関する理解の問題だと思います。 > Socket sock; > InputStream is = sock.getInputStream(); > これでなぜかis.read()が使える。 こちらの例の方が説明が簡単なのでこっちを使いますが,このとき変数isに入っているのは,InputStreamクラスそのもののインスタンスである必要はなく,その派生クラス(例えばByteArrayInputStreamやFileInputStream)のインスタンスであってもいい(*注),というのが継承の持つ機能の一つです。 注: 実際はInputStreamの派生クラスのうちのコンクリートクラスのどれかが入っていると考えるのが普通。 以下のようなコードを書いて動かしてみれば理解できるかもしれません。 abstract class AA { abstract void aMethod(); } class BB extends AA { void aMethod() { System.out.println("BB"); } } class CC { AA getAA() { return new BB(); } } class DD { public static void main(String[] args) { CC cc = new CC(); AA aa = cc.getAA(); aa.aMethod(); } }

  • koko_u_
  • ベストアンサー率18% (459/2509)
回答No.3

>>「実装を移動する」とはどのようなコトを指しているのですか? >これの実際の処理内容はどこに書いてますか? >public abstract int read() throws IOException; うーん。会話が成立していない。抽象メソッドだから、その派生クラスで read() は実装される。 ここまではいいですよね。 >>InputStream は抽象クラスなので、これは「InputStream の派生クラスをコンストラクタに渡せ」という意味です。 >同じ名前で派生クラスを作ろうとするとエラー(ループ)になるのでは?どうやってその派生クラスを作ったのか? >class InputStream extends InputStream() だから class HogeStream extends InputStream { ... } と「派生クラスを」定義するのです。 FilterStream のコンストラクタの引数は InputStream 型ですが、これは InputStream の派生クラスのすべてを 引数として受け取ることができることを意味しています。 これは OK?

osiete_kun
質問者

補足

いや、しかし、 Socketでは public InputStream getInputStream()throws IOException その説明では public HogeStream getInputStream() で無ければならず。

  • koko_u_
  • ベストアンサー率18% (459/2509)
回答No.2

>全然違うと思う。(またはその実装はどこにありますか?) 実装は InputStream の派生クラスの中。 >実装まで移動できない。 「実装を移動する」とはどのようなコトを指しているのですか?再度補足して下さい。 FilterInputStream のコンストラクタは InputStream を引数としていますね? InputStream は抽象クラスなので、これは「InputStream の派生クラスをコンストラクタに渡せ」という意味です。 InputStream の派生クラス HogeStream のインスタンス hoge をもって stream = new FilterStream(hoge); すると、stream の保持するメンバ変数 in は hoge です。 実行時にどこかで in.read() したときに、polymorphism が発動して、hoge に実装された read() が呼び出されます。

osiete_kun
質問者

補足

>「実装を移動する」とはどのようなコトを指しているのですか? これの実際の処理内容はどこに書いてますか? public abstract int read() throws IOException; >InputStream は抽象クラスなので、これは「InputStream の派生クラスをコンストラクタに渡せ」という意味です。 同じ名前で派生クラスを作ろうとするとエラー(ループ)になるのでは?どうやってその派生クラスを作ったのか? class InputStream extends InputStream()

  • koko_u_
  • ベストアンサー率18% (459/2509)
回答No.1

>ところがFilterInputStreamはInputStreamを変数にもちread()を呼び出している。 リンク先はまったく見てませんが、それが polymorphism というやつでしょう。 FilterInputStream は InputStream の「派生クラスとなる何か」をメンバーとして保持することができ、 インスタンス毎に様々な InputStream の派生クラスのインスタンスをそのメンバー変数として持てる。 そして、read() を呼び出すと、その派生クラスに応じた read() の実装が実行時に呼び出される。 そんな感じだと思う。 >Socket sock; >InputStream is = sock.getInputStream(); > これでなぜかis.read()が使える。 これも getInputStream() が InputStream の派生クラスの何かを戻しているはずです。

osiete_kun
質問者

補足

>そして、read() を呼び出すと、その派生クラスに応じた read() の実装が実行時に呼び出される。 全然違うと思う。(またはその実装はどこにありますか?) 実装まで移動できない。 プログラムにはread(byte b[])を使ったので 実際にread(byte b[])を使って移動してみると read(byte b[]) は read(b, 0, b.length) を呼び出す。 read(b, 0, b.length) はread()を呼び出す。 read()は public abstract int read() throws IOException; となっていてこれ以上移動できない。

関連するQ&A