広告 |
---|
■□■□■□■□■□■□■□■□■□■□■□■□■□■□■ 2009年12月23日 Java総合講座 - 初心者から達人へのパスポート 2009年11月開講コース 006号 セルゲイ・ランダウ バックナンバー: http://www.flsi.co.jp/Java_text/ ■□■□■□■□■□■□■□■□■□■□■□■□■□■□■ ------------------------------------------------------- ・現在、このメールマガジンは以下の2部構成になっています。 [1] 当初からのコース:毎週日曜の夜に発行 これは現在、中級レベルになっています。 [2] 2009年11月開講コース:毎週水曜の夜に発行 これは現在、初心者向けのレベルになっています。 ・このメールマガジンは、画面を最大化して見てください。 小さな画面で見ていると、不適切な位置で行が切れてしまう など、問題を起すことがあります。 ・このメールマガジンに掲載されているソース・コード及び 文章は特に断らない限り、すべて筆者が著作権を所有してい ます。また、これらのソース・コードは学習用のためだけに 提供しているものです。 ------------------------------------------------------- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ (2009年11月開講コース)006号 (当記事はvol.006のリバイバル(revival)版です。) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ======================================================== ◆ 00.はじめに ======================================================== 今回は、Humanクラスのインスタンスにメッセージを送って、自分 の氏名をしゃべらせるという操作を行ってみます。 Humanクラスのインスタンスは、いわば演劇の役者のようなもので、 自発的に勝手に行動したりはしません。 役者は自発的に勝手に行動することはなく、与えられた台本通りに 演技をするだけですね。逆に台本がないと演技はできません。 それと同じように、オブジェクト指向のプログラムでも台本のよう なものが必要なのです。それに従ってオブジェクトが行動をおこす のです。 ただ、実際の演劇では、役者が台本を読んでそれを記憶し、その内 容に従って演じるのに対し、オブジェクト指向プログラミングのア プリケーションでは、台本が各オブジェクトにメッセージを送って 指示をする、というイメージになります。 今回は、それをプログラミングしてみます。 そして、実際にEclipseを使ってプログラムの実行まで行ってみます。 ======================================================== ◆ 01.台本のクラス ======================================================== それでは、Humanクラスのオブジェクトにメッセージを送って、自分 の氏名を言わせるような、プログラムを作ってみましょう。 このプログラムは、いわばHumanのオブジェクトに演技をさせるため の、演劇の台本のようなものです。 Javaでは、この台本のような「もの」もオブジェクトとして扱い、 クラスとして定義することになっています。そして、そのクラスの中 にはmain( )メソッドと呼ばれるメソッドを作ってオブジェクトへの 指示を記述していくことになります。 ところで、花子さんに自分の氏名を言わせるためには、そもそも花子 さんが存在していなければなりませんし、花子さんが存在するために は、それ以前に花子さんが誕生していなければなりません。 (花子さんは人のインスタンスとします。) オブジェクト指向プログラミングにおいても、Hanakoというオブジェ クトにsayName()メソッドを実行するようにメッセージを送るために は、それ以前にHanakoというオブジェクトが誕生していなければなり ません。 オブジェクトを誕生させることを「オブジェクトを生成する」といい ます。 オブジェクトを生成するということは、インスタンスを誕生させると いうことです。 Javaでは、オブジェクトを生成するためにはnew演算子というものを 使い、次のような構文で記述します。 new コンストラクター コンストラクター(constructor)というのは、クラスが持つメソッド の一種で、オブジェクトの生成作業を担当する特殊なメソッドです。 コンストラクターのメソッド名はクラスの名前と同じである、という ルールになっており、たとえばHumanクラスのオブジェクトを生成した いときは、 new Human(); というように、Humanというメソッド名のコンストラクターを呼び出す ことになります。 (上記は引数を持たないコンストラクターになっていますが、引数を 持つコンストラクターを用意することもできます。) ところで、こうしてオブジェクトを生成しても、それだけでは困った ことになります。 たとえば、このオブジェクトにあとでメッセージを送りたいと思って も、このオブジェクトに呼びかけることができません。 呼びかけるための名前がないからです。 そこで、通常は、生成したオブジェクトをいったん変数に代入しておき、 変数名を使って呼びかけられるようにします。たとえば、 Human hanako; hanako = new Human(); というふうに、Human型の変数hanakoを用意し、hanakoにnew Human() の結果を代入してやるのです。 そうすると、生成されたHumanクラスのオブジェクトがhanakoに代入され、 以後はhanakoを通してオブジェクトに呼びかけを行うことができます。 たとえば、sayName()メソッドを実行して欲しければ、 hanako.sayName(); というふうにhanakoにメッセージ送信するという形式でオブジェクトに メソッドの実行を依頼することができます。 ここでちょっと注意していただきたいことは、メッセージを送るために 使うオブジェクトの名前は通常は変数名である、ということです。 現実の世界では、人に話しかける時には属性としての氏名を使って呼び かけますから、その点、大きく異なります。 ┌補足─────────────────────────┐ new演算子は、その後ろに書いたコンストラクターを呼び出して オブジェクトを生成させると同時に、そのオブジェクトを保管す るために必要な容量の記憶域をメモリー上に確保し、オブジェク トを保管する(メモリー上に記憶する)という操作を行います。 それと同時に、そのオブジェクトの記憶域のアドレスを返します。 hanako = new Human(); というふうに書いてある場合は、その返ってきたアドレスがhanako という変数に代入されます。 実は、=は演算子の一種(代入演算子と呼ばれる)で、右辺の値を 左辺の変数の記憶域に保管するという働きをします。 ここでは、右辺の値は、new演算子が返したアドレスになりますので、 そのアドレスがhanakoという変数の記憶域に保管されることになる のです。 なお、代入演算子(=)は、型に対するチェックを行うため、左辺の 変数の型と右辺の値の型が合っていないとエラーになります。 たとえば今の場合、右辺はHumanのオブジェクトであるため、もし 左辺の変数がHumanとは関係のないクラスの変数であった場合は、 コンパイルの時点でエラーが報告されます。 このようにJavaでは、コンパイルの段階でかなりの間違いを見つけ てくれるようになっています。 なお、もし new Human(); というようにオブジェクトの生成だけで終わってしまって、変数に 代入しなかったら、その後このオブジェクトは使えなくなってしま います。 あるいは、hanakoという変数に代入したとしても、その変数hanako 自体が削除されてしまうと、やはりこのオブジェクトは使えなくなっ てしまいます。 こういう場合は、オブジェクトが占める記憶域が無駄になるので、 Javaはこういった無駄な記憶域を適時削除して開放します。 この作業をガーベジ・コレクション(garbage collection:日本語 に訳すとゴミ回収??)と言います。 C++などではガーベジ・コレクションの機能がないため、しばしばメモ リーがパンク??するなどの問題を起こすプログラムを作ってしまうこ とがありますが、Javaはその点でもよくできています。 └───────────────────────────┘ それでは、いよいよこれからHumanのオブジェクトに演技をさせるため の、演劇の台本のようなものを作ることにしましょう。 次がその例です。Human(人)の演劇ということで、HumanTheater (人間劇場?)というクラス名にしてみました。 ----------------------------------------------- package jp.co.flsi.lecture.human; // [1行目] class HumanTheater { // [2行目] public static void main(String[] args) { // [3行目] Human hanako = new Human(); // [4行目] hanakoの誕生 hanako.memorizeName("Hanako"); // [5行目] 氏名を記憶 System.out.println("What is your name?"); // [6行目] 影の声 hanako.sayName(); // [7行目] } // [8行目] } // [9行目] ----------------------------------------------- では、1行目から順番に説明していきましょう。 package jp.co.flsi.lecture.human; この文は前回と同じく、これから定義するクラスをjp.co.flsi.lecture.human という名前のパッケージ(package)に入れることを宣言しています。 2行目の class HumanTheater は、これまでにも説明したように、「これからHumanTheaterという名前の クラスを定義します」という意味のクラス定義の宣言文です。 3行目の public static void main(String[] args) はmain( )メソッドを定義している文ですが、ここでは新しくstaticという キーワードが出てきました。 このstaticを指定すると、クラスのインスタンスを生成しなくてもメソッド が使えるようになります。 main( )メソッドは特殊なメソッドで、このメソッドを含むクラスをJVMで呼び 出すと自動的にmain( )メソッドが実行されるという仕組みになっています。 そして、その時点ではクラスのインスタンスなど存在していませんから、 main( )メソッドはstaticの指定をしておく必要があるのです。 以前作成したTest1というクラスのソース・コードを確認してください。 同じようなmain( )メソッドが記述されていますね。 そしてこのTest1というクラスを java Test1 というコマンドを使ってJVMで呼び出したのでした。 そうすると、自動的にそのmain( )メソッドが実行されたために System.out.println("こんにちは。"); System.out.println("いらっしゃいませ。"); の部分が実行されたのです。これで、Test1クラスの内容が理解できましたね。 あと、引数の String[] args の部分にある[]の記号も初めて出てきました。 これは配列型を示す記号なのですが、のちほど説明します。 今のところは、とりあえずmain( )メソッドの引数は普通はこのように書く のだ、と思っていてください。 ちなみに、Test1クラスのほうでは、 String args[] というふうに[]が変数名の後ろについていますが、これは、Javaの祖先にあたる C++(およびその祖先のC言語)で使われていた古い書き方です。 現在では、 String[] args のように変数名の前につけることが推奨されています。 これは型の指定を変数名の前にまとめて書くことによって統一性をもたらす ためです。 古い書き方をしても同じように働きますが、皆さんはできるだけ新しい書き方 をするようにしましょう。 4行目の Human hanako = new Human(); は、 Human hanako; hanako = new Human(); という2つの文をひとまとめにしたものです。 変数の宣言文と代入文はこのようにいちいち別々の文にする必要はなく、 1つの文にまとめて書くことが許されているのです。 つまり、4行目の1つの文で、コンストラクターHuman( )によってHumanのイン スタンスを生成し、それをHuman型の変数hanakoに代入することを意味します。 ┌補足─────────────────────────┐ 前回Humanクラスを定義したときには、コンストラクターなんて どこにも記述しませんでしたね。 実はコンストラクターを明示的に記述しなかった場合は、自動的 にJavaのコンパイラーがコンストラクターを用意してくれるの です。 このような自動的に用意されるコンストラクターのことをデフォ ルトのコンストラクター(default constructor)と呼ぶことが あります。 今使っているHuman( )というコンストラクターはこのデフォルト のコンストラクターです。 一方、インスタンスの生成の仕方を自分で明示したいときは、 コンストラクターをクラス定義の中に自分で記述しておく必要 があります。 なお、コンストラクターを明示的に記述した場合は、Javaが 自動的にデフォルトのコンストラクターを作ったりはしません。 └───────────────────────────┘ 続いて5行目を見てみましょう。 hanako.memorizeName("Hanako"); // [5行目] 氏名を記憶 ここでは、hanako変数が指しているオブジェクトに対してmemorizeName( ) メソッドを実行するようにメッセージを送っています。 つまり、hanakoのオブジェクトに自分の氏名を覚えさせているのです。 hanakoのオブジェクトは生成された直後には自分の氏名を知りませんから、 このようにして覚えさせておく必要があります。 メソッドの実引数が"Hanako"になっていることに注意してください。 前回のmemorizeName( )メソッドの定義を再確認すると、 public void memorizeName(String aName) { // [Humanの4行目] name = aName; // [Humanの5行目] } // [Humanの6行目] となっていました。つまり、引数はString型です。 そこで、実引数もString型のものを与える必要があるわけですが、"Hanako" というように2つの"ではさまれた文字列は、Javaコンパイラーによって、 String型のオブジェクトに変換されますから、適合しているわけです。 (Javaのプログラムの中で"Hanako"のように2つの"ではさまれた文字列を 見つけたときは、それをString型のオブジェクトと解釈して読み進めるよう にしてください。 そうすれば、すんなりをソース・コードを理解していくことができます。) そして、 hanako.memorizeName("Hanako"); というメソッドの呼び出し方をすると、仮引数のaNameがすべて実引数の "Hanako"に置き換えられます。 つまり、上記のHumanの4行目において、aNameが"Hanako"に置き換えられ、 Humanの5行目が name = "Hanako"; という文に置き換えられることになります。 このようにして、このメソッドが実行されると、nameという変数(これは 氏名を表現する属性でしたね)にはHanakoという文字列のデータを持つ String型のオブジェクトが代入されることになります。 以上をまとめると、 hanako.memorizeName("Hanako"); というメソッド呼び出しが行われると、hanakoのオブジェクトのnameという 属性に、Hanakoという文字列のString型オブジェクトが代入されることにな ります。 これで、hanakoさんが自分の氏名がHanakoであることを記憶することになり ます。 では、6行目に進みましょう。 System.out.println("What is your name?"); // [6行目] 影の声 これは、もうおわかりですね。 What is your name?という文字列を標準出力装置(ディスプレイ)に出力する ことになります。 これは、その次の行でhanakoさんに氏名を聞くため、そのことをディスプレイ を見ている人にわかるようにするために、わざと書いておいた文です。 ただ、これだと台本がWhat is your name?としゃべっているようなイメージ になってしまい、何かへんですから、コメントには影の声と書いておきました。 本来なら、別の人(たとえばyamada君とか)を表すオブジェクトも用意して、 そいつにWhat is your name?と言わせたほうが自然だったでしょう。 でもそうすると説明することがさらに増えてしまって、執筆に時間がかかって しまいますので、影の声で済ませました。 7行目に進みましょう。 hanako.sayName(); // [7行目] これは、前回でも説明したようにhanakoさんに自分の氏名を言わせるためのメッ セージですね。 こうすると、Humanクラスの中に定義されている public void sayName( ) { System.out.println("My name is " + name + "."); } の部分が実行されることになります。 そして、この時点では、さきほど述べたようにnameにはHanakoという氏名が セットされていますから、ディスプレイには、 My name is Hanako. という文字列が出力されることになります。 以上で、HumanTheaterクラスの内容はすべて理解できましたね。 では、次に、これらをEclipseを使ってプログラミングしてみましょう。 (1)まず、Eclipseを起動してください。起動の仕方を忘れた人は、以前のメール を読み返して確認してください。 (2)ワークスペースの選択のウィンドウが表示されたら、前回選択したのと同じ フォルダーがそのまま設定されているはずですので、そのまま「OK」ボタンを クリックします。 (3)Eclipseのプロジェクトを作りましょう。まず、メニュー・バーから 「ファイル」→「新規」→「プロジェクト」を選択します。 ┌補足─────────────────────────┐ プロジェクトというのは、Eclipseでは、プログラム開発によって できるファイルを入れるためのフォルダーの名前になります。 これは、ワークスペースの中に作られます。 プロジェクトと言えば、一般には何かを開発するときの計画や 開発事業全体を意味しますが、通常は、その現実のプロジェクト ごとにEclipseのプロジェクトを用意します。 └───────────────────────────┘ (4) 「新規プロジェクト」ウインドウが開きますので、その中で Javaプロジェクト を選択し、「次へ」ボタンをクリックします。 (5)「新規Javaプロジェクト」ウインドウが開きますので、その中で 「プロジェクト名」に JStudy1 と入力して、「完了」ボタンをクリックします。 画面左側の「パッケージ・エクスプローラ」というタブの下にJStudy1という フォルダーができていることを確認してください。 ┌補足─────────────────────────┐ プロジェクト名は自分で決めてもいいのですが、後で混乱すると いけませんので、ここに書いている名前にしておいてください。 └───────────────────────────┘ (6)続いてパッケージを作りましょう。メニュー・バーから 「ファイル」→「新規」→「パッケージ」を選択します。 (7)「新規Javaパッケージ」ウインドウが開きますので、その中で 「ソース・フォルダー」にJStudy1/srcが入っていることを確認 (もしくは入っていなければ入力)し、「名前」にパッケージの名前 jp.co.flsi.lecture.human を入力し、「完了」ボタンをクリックしてください。 「パッケージ・エクスプローラー」タブの下で、JStudy1フォルダー配下 のsrcフォルダーの下にjp.co.flsi.lecture.humanという名前が表示 されるのを確認してください。 (8)続いてクラスHumanを作りましょう。メニュー・バーより 「ファイル」→「新規」→「クラス」を選択します。 (9)「新規Javaクラス」ウインドウが開きますので、その中で 「名前」のところに Human と入力し、「ソース・フォルダー」にJStudy1/src、「パッケージ」に jp.co.flsi.lecture.humanが入っていることを確認(違っていれば修正) し、「修飾子」は「public」ではなく「default」を選択し、 「どのメソッド・スタブを作成しますか?」の 「public static void main(String[] args)」にチェック・マークが 付いていたら、それを除去(クリックすると除去できる)し、 「完了」ボタンをクリックします。 ┌補足─────────────────────────┐ クラスの修飾子としてのpublicについてはまだ説明していません が、通常はクラスにpublicを指定するのが普通です。 しかし、今回はまだ説明していませんので、とりあえずデフォ ルト(default)を選択しておきます。これらも、またのちほど 詳しく説明します。 └───────────────────────────┘ (10)少し待つと、「Human.java」というタブができて、その下に package jp.co.flsi.lecture.human; class Human { } というようにJavaのソース・コードの一部が自動生成されていること がわかります。 {と}との間の空白行に必要なコードを追加入力して、Humanクラスの ソース・コード -------------------------------------------------------- package jp.co.flsi.lecture.human; /* パッケージの指定 [1行目] */ class Human { // [2行目] Human(人)のクラス定義 private String name; // [3行目] 氏名の属性 public void memorizeName(String aName) { // [4行目] name = aName; // [5行目] } // [6行目] public void sayName( ) { // [7行目] 氏名を答えるメソッド System.out.println("My name is " + name + "."); //[8行目] } // [9行目] } // [10行目] -------------------------------------------------------- を完成させてください。(コメントの部分は入力しなくてもいいです。) 新しい空白行が必要なときは、行末でEnterキーを押して改行してください。 次の行が自動的に字下げされますが、これはプログラムを見やすくするために 有用な機能ですから、そのまま利用してください。 なお、日本語の文字(漢字やかな等)以外はすべて半角で入力(直接入力) することを忘れないでください。 上記のソース・コードをコピー&ペーストしたい人もいるかもしれませんが、 最初のうちは、できるだけキーボードをたたいて、手で入力するようにして ください。 Eclipseがある程度入力を支援してくれますので、たとえば、左括弧「(」を 入力すると右括弧「)」が自動的に付いてきたり、左中括弧「{」を入力して 改行すると右中括弧「}」が自動的に付いてきたりしますので、よけいに入力 したりしないようにご注意ください。 ┌補足─────────────────────────┐ Stringのような既存の名前に対しては、先頭の一部の文字を入力 した後でCtrlキーを押しながらスペース・キーを押すとその文字 で始まる名前が自動的にリストされますので、その中から選択す ることもできます。 この機能を「コンテンツ・アシスト」といいます。 たとえば、Stringと入力したいときにはStrと入力し(コンテンツ・ アシスト機能では文法も認識されているので、どこでStrと打っても 同じように反応してくれるわけではありませんが、適切な場所でStr と入力すると)Ctrlキーを押しながらスペース・キーを押すことに よって、Strで始まるクラスの名前がリストされるはずです。 その中で「String - Java.lang」というのを選択し、Enterキーを 押してください。 (ここで、Java.langというのはStringクラスがはいっているパッ ケージの名前です。) 簡単な名前であれば手で入力したほうが速いかも知れませんが、 でも、つづりを正確に覚えていないときなどは、この機能が役立 ちます。 └───────────────────────────┘ (11)入力が終わったら、保管しておきましょう。メニュー・バーから 「ファイル」→「保管」を選択してもいいですが、保管は頻繁に行う ことですので、CtrlキーとSキーを同時に押す(以後、「Ctrl + S」 というふうに表記する)というショートカット・キー(ショートカット・ キーとは、日本語に直訳すると「近道キー」とでも言うべきもので、 操作を速くするためにキーだけで操作することを言います)で保管できる ことも覚えておきましょう。 というわけで、今後の保管はこのショートカット・キーで行いましょう。 保管するとコンパイルが自動的に行われますので、ソース・コードの中に 何か間違いがあると、エラーが表示されます。 もし、ソース・コードの左側の外枠に赤いバツのマーク(×)が表示され ていたら、それはエラーの印です。 その場合は、下のほうの「問題」というタブの下にエラーの説明が表示さ れるのですが、まだJavaをよく知らない段階ではわけがわからないと思う ので、それはとりあえず無視して、ソース・コードをよく見直して、 入力し間違えているところを修正してから再度保管しなおしてみましょう。 続いて、HumanTheaterクラスを作りましょう。 (12)メニュー・バーより「ファイル」→「新規」→「クラス」を選択します。 (13)「名前」のところにHumanTheaterと入力し、「ソース・フォルダー」 にJStudy1/src、「パッケージ」にjp.co.flsi.lecture.humanという名前が 入っていることを確認します。さらに、 「修飾子」は「public」ではなく「default」を選択し、 「どのメソッド・スタブを作成しますか?」の 「public static void main(String[] args)」にチェック・マークを 入れておきます。 (HumanTheaterクラスにはmain( )メソッドを組み込みたいので、この ようにチェック・マークを入れておくのです) そして「完了」ボタンをクリックします。 (14)少し待つと、「HumanTheater.java」というタブができて、その下に package jp.co.flsi.lecture.human; class HumanTheater { /** * @param args */ public static void main(String[] args) { // TODO 自動生成されたメソッド・スタブ } } というようにJavaのソース・ファイルの一部が自動生成されていることが わかります。 (コメントの行が見苦しいですが、邪魔なら削除してしまってかまいません。) Humanの時と同様にソース・コードを追加入力して、 HumanTheaterのソース・コード ----------------------------------------------- package jp.co.flsi.lecture.human; // [1行目] class HumanTheater { // [2行目] public static void main(String[] args) { // [3行目] Human hanako = new Human(); // [4行目] hanakoの誕生 hanako.memorizeName("Hanako"); // [5行目] 氏名を記憶 System.out.println("What is your name?"); // [6行目] 影の声 hanako.sayName(); // [7行目] } // [8行目] } // [9行目] ----------------------------------------------- を完成させてください。 (コメントの部分は入力しなくてもいいです。) (15)入力が終わったら、保管しておきましょう。 (16)続いて、HumanTheaterを実行してみましょう。 パッケージ・エクスプローラー内(「パッケージ・エクスプローラー」タブの 下の領域)の中でHumanTheaterを右クリックし、「実行」→「Javaアプリケーション」 を選択しましょう。 しばらくして、下のほうの「コンソール」タブの下に What is your name? My name is Hanako. という文字列が表示されれぱ成功です。 (17)Eclipseを終了してください。 ================================================ ◆ 02.演習問題 ================================================ さきほど作ったmain( )メソッドの hanako.memorizeName("Hanako"); // [5行目] 氏名を記憶 の下に1行追加し、 hanako.memorizeName("Suzuki"); というコードを入力したあと保管し、実行してみましょう。 結果はどうなりますか。 ====================================================== ◆ 03.前回の演習問題の答 ====================================================== sayName( )メソッドのコードを public void sayName( ) { System.out.println("私の名前は、" + name + "です。"); } というように書き換え、今回作成したようなmain( )メソッドの中で Human hanako = new Human(); hanako.memorizeName("花子"); hanako.sayName(); というように、Human型のオブジェクトに花子という名前を覚えさせ てからsayName( )メソッドを呼び出せばいいですね。 ◆編集後記◆━━━━━━━━━━━━━━━━━━━━━━━━ ☆最後まで読んでくださってありがとうございます。 ☆次回は、Humanクラスを改良してもう少し複雑なことをやらせてみ ます。 その後、ウィンドウを表示するようにプログラムを改良し、ウィンド ウを通してHumanオブジェクトにいろいろな振る舞いをさせてみます。 お楽しみに。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ★ホームページ: http://www.flsi.co.jp/Java_text/ ★このメールマガジンは 「まぐまぐ(http://www.mag2.com)」 を利用して発行しています。 ★バックナンバーは http://www.flsi.co.jp/Java_text/ にあります。 ★このメールマガジンの登録/解除は下記Webページでできます。 http://www.mag2.com/m/0000193915.html ★このメールマガジンへの質問は下記Webページにて受け付けて います。わからない所がありましたら、どしどしと質問をお寄 せください。 http://www.flsi.co.jp/Java_text/ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ Copyright (C) 2009 Future Lifestyle Inc. 不許無断複製 |