広告

■□■□■□■□■□■□■□■□■□■□■□■□■□■□■
                      2009年12月16日

    Java総合講座 - 初心者から達人へのパスポート
                  2009年11月開講コース 005号

                                セルゲイ・ランダウ
 バックナンバー: http://www.flsi.co.jp/Java_text/
■□■□■□■□■□■□■□■□■□■□■□■□■□■□■


-------------------------------------------------------
・現在、このメールマガジンは以下の2部構成になっています。
[1] 当初からのコース:毎週日曜の夜に発行
   これは現在、中級レベルになっています。
[2] 2009年11月開講コース:毎週水曜の夜に発行
   これは現在、初心者向けのレベルになっています。
・このメールマガジンは、画面を最大化して見てください。
小さな画面で見ていると、不適切な位置で行が切れてしまう
など、問題を起すことがあります。
・このメールマガジンに掲載されているソース・コード及び
文章は特に断らない限り、すべて筆者が著作権を所有してい
ます。また、これらのソース・コードは学習用のためだけに
提供しているものです。
-------------------------------------------------------


━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
(2009年11月開講コース)005号
 (当記事はvol.005のリバイバル(revival)版です。)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━


========================================================
◆ 00.はじめに
========================================================

今回は、EclipseによるJavaのプログラミングの第一歩として極め
て簡単なプログラムを作ってみることにします。

途中で、Javaの文法やキーワードなども少しずつ解説していきます
が、これらは、そのうちに適切な時点で整理して解説しなおす予定
です。

今のところは、個々の文法やキーワードを覚えることよりも、ソース・
コードのそれぞれの意味をひとつひとつ理解していくことに重点を
おいて学んでいってください。



========================================================
◆ 01.極めて単純化した人のクラス
========================================================

以前お話したように、オブジェクト指向は、もともとは現実世界の
オブジェクトをコンピューター上で表現するために編み出されたも
のです。

今回は現実世界のオブジェクトの一つの例として、人のオブジェク
トをJavaでプログラミングすることを考えてみます。

人にはさまざまな属性がありますが、今回は話を簡単にするために、
人の氏名だけを属性として取り上げ、自分の氏名を聞かれたら答える
という振る舞いをするだけの極めて単純なオブジェクトをプログラミ
ングしてみます。

下記は、そのような単純な人(Human)のクラスをJavaで記述した
例です。


--------------------------------------------------------
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行目]
--------------------------------------------------------


1行目から順番に説明していきましょう。

package jp.co.flsi.lecture.human;

この文は、これから定義するクラスをjp.co.flsi.lecture.human
という名前のパッケージ(package)に入れることを宣言する文です。
Javaの言語では、文の終わりはセミコロン(;)で区切られます。

パッケージというのは、同じ名前のクラスを別の同名のクラスと区別す
るための仕組みです。
同じパッケージの中には同じ名前のクラスは1つしか作ることができま
せんが、別々のパッケージに作れば同じ名前のクラスを複数存在させる
ことができます。

(クラスのほかにインターフェース(後述)というものもあり、これも
やはり別々のパッケージに入れることによって、同名のものを複数存在
させることができます。)

具体的には、クラスの名前の前にパッケージの名前をつけることによっ
て、どのパッケージに入っているクラスを使いたいのかを明示できます。

例えば、家具のテーブルの意味のTableというクラスと、プレゼンテー
ションなどで使う表という意味のTableというクラスでは、名前が重複
してしまって困りますが、テーブルのほうのTableはfurnitureという
パッケージに入れておいてfurniture.Tableと明記し、表のほうは
presentationというパッケージに入れておいてpresentation.Table
と明記するようにすれば、明確に区別することができる、という具合
です。

また、パッケージは一つのグループを表現する役割も持っており、後述
するprotectedというキーワード(Java言語であらかじめ定義されてい
る単語)とも関係があります。

詳しいことは別の機会に再度お話しますが、今の段階ではとりあえず、
パッケージはクラスを入れる入れ物、という大雑把なイメージでとらえ
ていただいても結構です。

なお、自分で作るクラスを入れるパッケージの名前は、自分で決めて
かまわないのですが、世界的にユニーク(唯一)な名前にするために、
インターネットのドメイン名をひっくり返したような名前にすること
が推奨されています。

たとえば、flsi.co.jpというドメイン名の会社であれば、co.jp.flsi
という名前で始まり、そのうしろに会社内でユニークな名前(上記1行目
の例ではlecture.human)を付け足してjp.co.flsi.lecture.human
というような名前にします。

このようにしてパッケージ名をユニークなものにしておけば、世界中の
人たち(あるいは組織)と、お互いが作ったパッケージを交換し合って
も名前が重複してしまうなどの問題が生じません。


1行目の後ろのほうを見てみましょう。

/* パッケージの指定  [1行目] */

この/*と*/で囲まれた部分は、コメントです。つまり、何らかの説明文
です。

このコメントの部分は、コンパイルの時点では無視され、バイトコード
の中にははいりません。
したがって、プログラムの実行にはなんの影響もしません。

つまり、コメントは、ソース・コードを読む人に説明を与えるためだけ
のものです。

なお、2行目の

// [2行目] Human(人)のクラス定義

のように//で始めるコメントもあります。この場合は、//からその行の
終わり(行末)までがコメントということになります。

やはりこの部分も、コンパイルの時点で無視されます。

なお、コメントを/*と*/で囲んで表す場合は、/*と*/の間に行が複数
あってもかまいません。
つまり、複数行のコメントを書くことができます。


2行目の

class Human

は、以前にも説明したように、「これからHumanという名前のクラスを
定義します」という意味の一種の宣言文です。
そして、それに続く中括弧({と})の間でクラスの内容を記述します。

なお、中括弧の{と}は階層的に何度も使われ、上の例でも何度も中括弧
が書かれていますが、クラス定義の範囲を表すものは一番外側の中括弧
になります。
つまり、2行目と10行目の中括弧で囲まれた範囲がクラス定義になります。


3行目の

private String name;

は、属性の氏名を記述するためのものです。Javaでは属性の名前は英数字
にする必要がある(現在のJavaでは漢字も使えるが、将来プログラムを国際
的な場で提供することを考えると英数字にしておくことが望ましい)ので、
「氏名」という漢字は使わず、代わりに「name」という英語にしたものです。

このnameは変数(variable)と呼ばれるものです。
Javaでは属性は変数を使って表現されます。

┌補足─────────────────────────┐
変数は属性を表現するものばかりではなく、属性とは関係なく
必要な時点で必要に応じて定義されるものもあります。

Javaでは、特に属性を表現する変数をフィールド(field)と呼
んで、他の変数と区別することがあります。
フィールドはC++言語のデータ・メンバー(data member)または
メンバー変数(member variable)に相当します。

こういったJavaに関わる用語の意味は、下記のWebページで調べ
ることができます。

http://java.sun.com/docs/glossary.html
└───────────────────────────┘


変数というのは中学の数学で習っていますね。中学ではxとかyとかで変数
を表していたはずです。

ところが、変数にはxやyという文字を使わなければならないという義務が
あるわけではないので、ここではxやyの代わりにnameという名前(変数名
という)をつけました。
こういう変数名にしたほうが氏名を表すことがすぐにわかるからです。

逆にもし、xとかyという変数名にしてしまったら、何を表す変数なのか
さっぱりわからなくなってしまいます。

なお、変数はいろいろな値をとりえるものを仮に変数名で表現しておくもの
ですが、Javaでは、とりえる値が数学とは違ってきます。
数学では変数のとりえる値は数だけでしたが、Javaでは、数だけでなく
(人の氏名のような)文字列その他、いろいろな値をとることができます。


ただし、Javaの変数がいろいろな値をとることができると言っても、かって
にいろいろな値をとっていいというわけではなく、その「型」(type:タイプ)
をあらかじめ宣言しておくことが義務付けられています。

型(タイプ)というのは値の種類を意味します。


そして、さきほどの

private String name;

は、nameという変数がString型であることを宣言しています。

Stringというのは文字列の型です。

もう少し正確に言うと、StringはJavaの言語にあらかじめ用意されている
クラスの名前であり、文字列を表現するオブジェクトのクラスとして定義
されているものです。

Stringクラスの詳細については、のちほど説明します。


┌補足─────────────────────────┐
もともとは、一つの文字のことを英語でcharacterと呼び、文字を
いくつか連ねた、いわゆる文字列のことをcharacter stringと言っ
ていたことから、それを略したstringだけでも文字列を意味するよう
になったものです。

stringとはもともとは糸や紐のことを意味しますが、ここでは数珠
(じゅず)の糸のことをイメージしており、文字を糸で数珠つなぎに
したものをイメージしてcharacter stringと呼び、それを略して
stringと呼んでいたのでした。

Javaでは、文字列を表現するオブジェクトのクラスがStringという
名前であらかじめ定義されており、我々が自由に利用することが
できます。
└───────────────────────────┘


文字列と数では型(種類)が異なることはわかると思うのですが、
仮に変数の値を数だけに限定した場合でもいろいろな型があります。

たとえば、体重と身長はどちらも数で表現されるものですが、種類が
異なりますね。

太郎君の体重と花子さんの身長を足し算しても意味はありませんね。
「太郎君の体重は80kgで、花子さんの身長は160cmです。全部でいくら
になるでしょう。」なんていう問題は教科書にはないはずです。
あったら教科書検定を通らないでしょう。

一方、「このエレベーターは合計500kgまでの人を積載できます」と
いうように、体重どうしならば同じ種類なので足し算することができ
ます(現実にはエレベーターに乗っている人の体重をいちいち聞いて
確認するわけにはいきませんから、実際のエレベーターでは「定員8名」
というように平均体重から換算した人数で表記しているのが普通だと
思いますが)。

このように数だけに限定してもいろいろな種類があり、種類の異な
る数では足し算などの演算ができないなど、いろいろな制約が生じ
ることになります。

┌補足─────────────────────────┐
(物理学においては、体重と身長では次元が異なるために足し算
ができないと説明されるのですが、話がかえってむずかしくなる
のでやめておいて)とりあえず、体重と身長ではkgとcmという
ふうに単位が異なることから種類が異なることが理解できると思
います。
└───────────────────────────┘

こういった種類の異なる値をごちゃまぜにして、たとえば上記のように
誤った足し算をしてしまったりすると、問題を起こすことがありますの
で、Javaにはそういった種類をきちんとチェックする仕組みが用意され
ています。

そのために、変数にはあらかじめ型を宣言しておくことが義務付けら
れているのです。

こういった型(type)は、Javaでは多くの場合、String型のように
クラスを使って表現します。

クラスはオブジェクトの種類を意味しますから、型の表現に利用
できることは理解できると思います。


しかし、クラス以外にも型を表現するものがあります。

たとえば、Javaでは一番基本的な型として基本データ型(fundamental
 data type)と呼ばれるものがあらかじめ用意されています。

(基本データ型やクラス以外にも、インターフェースや配列という型も
ありますが、これらについては後述します。)

基本データ型には、たとえば、intやcharといったものがあります。

intは整数を表現する型で、整数のことを英語でintegerと言うことから
来ています。

また、charは文字(文字列ではなく一つの文字)を表現する型で文字の
ことを英語でcharacterと言うことから来ています。

(厳密に言うと、charでも整数を扱うことができます。また、int以外
にも整数を表現する型があります。詳しくは後述。)

その他いくつかの基本データ型がありますが、のちほどまとめて説明い
たします。

なお、基本データ型はオブジェクトではありませんので、注意してくだ
さい。
オブジェクトではないというのはどういうことかというと、メソッドを
持たず、純粋にデータだけの値を持つという意味です。

基本データ型はプリミティブ型(primitive type)と呼ばれることも
あります。primitiveというのは原始的とか素朴とかいう意味で、オブ
ジェクト指向の概念が誕生する前の古い時代からあった型であるために
このように呼ばれます。

オブジェクトという言葉自体、いろいろな意味で使われますので混乱の
もとになっていますが、オブジェクト指向で言うオブジェクトは、属性
とメソッドを持ったもの、すなわち、データだけでなくメソッドも持って
いるものを意味します。

intやcharにはメソッドはありません。(ただし、整数や文字をオブジェ
クトとして扱いたい人のためにIntegerやCharacterという名前のクラス
も用意されており、これらにはメソッドがあります。)

一方さきほどのStringは、クラスの名前であり、オブジェクトを表現し
ていますから、データだけでなく、メソッドも持っています。

┌補足─────────────────────────┐
参考までに、オブジェクト指向が誕生した最初の頃から存在する
Smalltalkという言語がありますが、この言語では整数でも文字でも
なんでもかんでもが、すべてオブジェクトになっています。

非常に徹底したオブジェクト指向言語なんですね。
└───────────────────────────┘


ところで、プログラムの実行時にはコンピューター内のメモリー上に、
一つ一つの変数に対応した記憶場所(以後、記憶域と呼ぶ)が確保され
ます。

そして、intやcharといった基本データ型の変数の場合には、変数にデータ
を代入するという操作は、その記憶域にデータそのものを記憶するという
処理によって実現されます。

基本データ型では、型によって必要な記憶容量が決まっているので、
それでいいのですが、たとえばString型の場合には、変数にはデータでは
なくオブジェクトを代入するという操作を行うことになります。
そして、オブジェクトの大きさは型によって決まるわけではありません。
たとえばString型の場合は、文字列のサイズ(文字の個数)がいくつに
なるかは型によって決まっているわけではありませんから、変数の記憶域の
大きさをあらかじめオブジェクトの大きさに合わせておく、ということは
できないのです。

それで、Javaでは、String型などのようなオブジェクトに対する変数
の場合には、変数に値を代入するという操作は、オブジェクトそのもの
を変数の記憶域に入れるのではなく、オブジェクト自体は別の記憶域に
記憶しておいて、そのアドレス(オブジェクトの記憶場所を示す住所あ
るいは番地のようなもの)を変数の記憶域に入れるようにしています。

そうすることによって、変数を通してオブジェクトを参照することが
できるようになります。

このように変数の記憶域に直接その値(値と言っても、今の場合はデータ
ではなくオブジェクト)を入れるのではなく、値の記憶場所を参照するアド
レスを入れておくような形式の変数を「参照型」(reference type)と
呼ぶことがあります。


したがって、今のnameという変数はString型であり、参照型であると言えます。

参照型にはStringなどのクラスのほかに、インターフェースや配列というもの
もありますが、これらについては後述します。



Javaでは、通常、フィールド(変数)を

アクセス制御 変数の型  変数の識別子;

という形式で宣言します。

変数の識別子(しきべつし)とは変数名のこと(識別子とは名前のこと)で、
さきほどの例ではnameになっていました。

変数の型は、さきほどの例ではStringになっていたことは言うまでもあり
ません。

最後のセミコロン「;」は前に述べたように、文の終わりを示す記号です。
これは日本語文の「。」や英文のピリオド「.」に相当するものです。

それでは、アクセス制御とは何かということなんですが、文字通り、
アクセスの仕方を制御するためのキーワードを意味します。

そして、アクセス制御には、「public」という「公開する」ことを意味す
るキーワードと、「private」という「隠蔽する」ことを意味するキーワー
ド、および「protected」という「一般には隠蔽し、同族内でのみアクセス
(使用)できる」ことを意味するキーワードがあります。


さきほどの例では、

private String name;

というようにアクセス制御としてprivateが指定されています。

privateは、「自分だけがアクセス(使用)することができ、他者にはアク
セスさせない、すなわち、隠蔽する」ことを意味するキーワードです。


したがって上記のnameの宣言文は、「nameには自分だけがアクセスするこ
とができ、他者にはアクセスさせない、すなわち、隠蔽する」ことを宣言し
ています。

こういう宣言をしておけば、変数nameは、他者からは見ることもいじること
もできません。


オブジェクト指向では、オブジェクトの属性(データ)は隠蔽するのが原則
ですから、通常は、このように属性にはprivateを指定します。



ところで、普通の人は、自分の名前くらいは知っているものですが、それは
最初から頭の中にはいっているわけではなく、ある時点で覚えたものです。

通常は幼い頃に親たちから名前で呼びかけられているうちに、覚えるので
しょう。
自分では名前を覚えた自覚はないかも知れませんが、すくなくとも人には
自分の名前を覚えるという振る舞いがあることは確かです。

したがって、Humanクラスにも自分の名前を覚えるメソッドを用意しておき
ましょう。

これが、4行目から6行目までの

public void memorizeName(String aName) { // [4行目]
     name = aName;     // [5行目]
}  // [6行目]

の部分です。

Javaでは、メソッドの識別子(メソッドの名前)の後ろに括弧「( )」を
つけることによってメソッドを表わすことになっています。

したがって、ここでは、memorizeNameという名前のメソッドが定義されて
いることがわかります。

ところで、このメソッドの表現方法は、C++という他のオブジェクト指向
言語に由来しています。
Javaは主にC++をまねして作られた言語だからです。

C++などの他の言語ではメソッドのことを関数と呼ぶことがありますが、
このことからもわかるように、この括弧をつける表現は、数学における関数
の表現から来ています。

┌補足─────────────────────────┐
C++では特にメソッドのことをメンバー関数と呼ぶことがあり、メンバー
変数とメンバー関数を合わせて、メンバー(member)というふうに総称
することがあります。
このことから、Javaでもやはり、フィールドとメソッドを合わせてメンバー
と呼ぶことがあります。
└───────────────────────────┘

(中学の一年生などで、数学の関数についてまだ習っていない人はそのうちに
学校で習いますから楽しみに待っていてください。
以下は、関数についてすでに習っている人向けの説明です。)

数学では関数を「f(x)」などの形式で表現しますね。
たとえば、「変数xの値を決めれば、変数yの値が決まる」というxとyの関係を

y = f(x)

というふうに表現することがありますね。

この( )の中に書かれた変数のことを、関数の「引数(ひきすう)」(argument)
と呼びます。

引数は2個以上あることもあり、例えば、

z = f(x, y)

という表現だと、2つの引数xとyの値が決まればzの値が決まるということに
なります。

ところで関数を英語でfunctionと言い、このf(x)やf(x, y)のfは、わかりやす
くするためにfunctionの頭文字を取ったもので、特にfとしなければならない義務
があるわけではありません。どんな文字で表してもいいのです。

そこで、上記の4行目〜6行目ではfの代わりにもっとわかりやすいmemorizeName
という名前を使いました。
これならname(氏名)をmemorize(記憶)するための関数だということが即座に
わかりますね。

また、引数をxやyという名前にしなければならないという義務もありませんので、
aNameというわかりやすい名前にしてあります。
こうすればaNameは一つの氏名を表す変数だということが一目瞭然ですね。


このようにJava(およびその祖先にあたるC++など)のメソッドは数学の関数に
類似した表現を取っているわけですが、ただし、数学そのものではありませんから、
やはり違うところがあります。

たとえば、引数であるaNameという名前の前にStringが書かれていますが、これら
は変数の型を表します。
引数の宣言は、変数の宣言の一種なので、このように変数の型を指定することが義務
づけられているのです。
(注意:引数は変数の一種ですが、フィールドと異なり、アクセス制御は指定できま
せん。)

ところで、

y = f(x)

という数式では、引数xに何らかの値を代入するとf(x)の値、すなわちyの値が決
まることを意味していますね。
実際にはf(x)は何らかの計算式を表現するものです。例えば、

f(x) = 2x + 5

の場合には、y = f(x)は、y = 2x + 5という数式を表現しています。

つまり、y = f(x)という数式はxに何らかの値を代入すると、xの値を使って2x + 5
の計算をし、その計算結果をyに代入することを意味しています。

これを一般化すると、f(x)の引数xに何らかの値を代入するとf(x)は何らかの値を
返してくれるという言い方ができます。

これと同じくJavaのメソッドも普通は、引数に何らかの値を代入してやると、
メソッドが何らかの値を返してくれることになっています。

この返してくれる値のことを「戻り値」(または返り値)と呼びます。

ただし、Javaのメソッドの場合は、数学と異なり、戻り値を返さない場合もあり
ます。

上記の4行目〜6行目において、識別子memorizeNameの前に書いてある「void」と
いうのは、戻り値を返さないことを表わすキーワードです。


一般にメソッドは、下記のような構文で定義します。

アクセス制御  戻り値の型  メソッドの識別子(引数1の型   引数1の識別子, 
引数2の型   引数2の識別子, ...) { 処理内容 }

メソッドの引数は、1つだけでもいいし、2つでもいいし、3つ以上でもいい
(あるいは無くてもいい)ので、それを上記では「, ...」と書くことによって
表現しておきました。

戻り値の型や引数の型は普通の変数の型(たとえばintやStringなど)を指定でき
ますが、戻り値を返さない場合は代わりにvoidを指定することになっています。

また、引数がない場合は、括弧( )の中を空っぽにしておくことになっています。

先ほどのf(x) = 2x + 5という数式はf(x)という関数が引数xに対して2x + 5という
計算処理をすることを表現していましたが、Javaのメソッドでも引数に対してどの
ような処理をするのかを記述しなければなりません。

その処理は括弧( )に続く中括弧{ }の中に記述することになっています。

memorizeName( )メソッドの場合は、5行目のような処理が記述してあります。

     name = aName;     // [5行目]

これは、引数aNameの値を属性のnameに代入することを意味します。

Javaの等号「=」は数学と異なり、「等しい」という意味ではなく、「右辺の値を
左辺の変数に代入する」という意味を表すのです。


なお、引数はそのメソッドの中だけで使われるものであり、メソッドの外には関係
しません。
例えば、aNameという引数は、nameという変数(属性)と名前こそ似ているものの
(というよりわざと似ている名前にしたのですが)、そのままでは何の関係もあり
ません。5行目の代入の式によって初めて関係ができるのです。

このようにメソッドの定義で宣言した引数は仮引数(かりひきすう)と呼ばれること
もあり、あくまでメソッドの定義時だけに使われる仮の変数にすぎません。
メソッドの使用時には仮引数が表面に現れることはなく、他の具体的な数や具体的な
文字列や具体的な変数(実引数と呼ぶことがある)が仮引数に取って代わることに
なります。
このことについては、後に詳しく述べます。

あと、メソッドのアクセス制御も先ほどの変数の時に説明したアクセス制御と同じで、
publicとprivateとprotectedというキーワードがあり、その働きは変数の宣言の
場合と同じです。

上記のmemorizeName( )メソッドでは、publicが指定されていますが、これは「公開」
することを意味します。
つまり、「このメソッドは誰もが自由に使ってよい」ということを指定するものです。


次に、7行目〜9行目の説明に移ります。

public void sayName( ) {     // [7行目] 氏名を答えるメソッド
     System.out.println("My name is " + name + ".");   // [8行目]
}     // [9行目]

これは、氏名を答えるメソッドとして記述したものです。氏名を聞かれたら、
自分の氏名を言うメソッドです。
氏名を言うわけですから、sayNameという名前にしました。

このようにクラスや変数やメソッドには意味のよくわかる名前をつけるのが鉄則です。
変数やメソッドの名前には日本の文字も使えますが、プログラムがのちに世界中で
使われるような可能性があることを考えると、英語の名前にしておいたほうが都合
がいいでしょう。


見ての通り、sayName()メソッドには引数がないですね。
また、voidと指定されていますから、戻り値もないわけです。
そしてpublicと指定されていますから、誰でも自由に使えるメソッドだということに
なります。

8行目がこのメソッドの処理内容になっていますが、System.outというのは以前にも
出てきましたね。
以前Test1というクラスを作ったときにも、System.outというコードがありましたが
まだ説明していません。

これはいったい何かということなんですが、細かく説明しているとまたまたずいぶん
長い文章になってしまいますので、後述することにして、今回はごく大雑把な説明を
しておきます。


このSystemというのは、システムすなわちコンピューター・システム全体を表現する
クラスです。
そして、コンピューター・システムは複合オブジェクトですから、その中にはさまざま
なオブジェクトが組み込まれています。
そのうち、標準的な出力装置を表現しているのがoutです。

つまりSystem.outというのはコンピューターに組み込まれている(組み込まれている
と言っても実際には通常、外付けされていると思いますが)標準出力装置のオブジェ
クトを表します。

そして、println( )というのはその標準出力装置オブジェクトのメソッドです。
そして、println( )というメソッドは、文字通りプリントをしてくれるメソッドです。

といっても最近のコンピューターの標準出力装置といったらディスプレイでしょうから、
プリント(print)という言い方は、へんですね。

プリントと言わずに表示と言ってくれたほうがわかりやすいですね。

でも、これは昔ディスプレイがなくて標準的な出力装置がプリンターだった頃からの
名残でもあり、今でも標準出力装置がプリンターだというコンピューターも残っている
ようなので、いまだにprintという言葉が使われているのです。

このprintln( )メソッドは、引数として与えられたものをプリントあるいは表示
(出力)してくれます。


8行目では、

"My name is " + name + "."

というのが引数として与えられていますが、データとして与えたい文字列を具体的に
記述するときは"My name is "のように文字列を2つの"で囲むというルールになって
います。

┌補足─────────────────────────┐
実を言うと、この2つの"で囲んだ文字列はたんなるデータでは
なく、オブジェクトになります。

Javaのシステムは、プログラムの中に2つの"で囲まれた文字列
を見つけると、この文字列をデータとして持つStringクラスの
オブジェクト(インスタンス)を生成するのです。
└───────────────────────────┘

その"My name is "の次に+のマークがあり、そのとなりにnameという先ほどの属性
の変数が指定されていますが、nameはString型でしたね。

こうしておくと、"My name is "という文字列の右側にnameの値の文字列が付け
足された文字列が生成されます。

┌補足─────────────────────────┐
この+はもともとは足し算の演算子(+や-などの足し算や引き算
などの演算を表す記号を演算子と言います)ですが、Javaでは、
それがStringのオブジェクトにも拡張されて用いられ、Stringの
オブジェクトに対しては、「+の右側のオブジェクトの文字列を
左側のオブジェクトの文字列の後ろに付け足した文字列を持つ
オブジェクトを生成する」という演算をするようになっています。
└───────────────────────────┘

同様に、nameのうしろにさらに+ "."というのが記述されていることによって、
最後にピリオドが付け足された文字列が生成されることになります。

これで、例えばnameという変数に"Hanako"という文字列がデータとして入って
いたとすると、

System.out.println("My name is " + name + ".");

という文は、

My name is Hanako.

という文字列を標準出力装置(ディスプレイ)に表示してくれることになり
ます。

ところで、ここではprintln( )というメソッドを使いましたが、以前Test1
というクラスを作ったときにはprintln( )ではなく、print( )というメソッ
ドを使いました。
これらのメソッド名はlnがついているかついていないかだけが違いますね。

このlnは、line(行)を略したもので、「行を出力する」すなわち文字列を出力し、
行が終わったことを示すために改行することを意味します。
つまり、println( )のほうは文字列を表示したあと改行してくれるのですが、
print( )のほうは文字列を表示したあと改行はしません。それだけの違いです。


ところで、オブジェクトに何かを依頼したい時には、そのオブジェクトに
メッセージを送らなければならないのでしたが、実は、この

System.out.println("My name is " + name + ".");

という文が、まさにオブジェクトにメッセージを送る文なのです。

この文を日本語風に翻訳?すると、

「System.outさん、"My name is" + name + "."をprintlnしてください。」

というメッセージになります。もっと日本語らしく翻訳?すると、

「標準出力装置さん、"My name is" + name + "."の内容を出力してください。」

というメッセージになります。


このように、通常、オブジェクトへのメッセージ送信は、

オブジェクト.メソッド名(実引数);

という形式で表現されます。なお、上記のオブジェクトのところには通常は、
オブジェクトの変数名が入ります。

たとえば、hanakoという名前の変数にHumanクラスのオブジェクトが入ってい
る時(正確に言うと、hanakoという変数の記憶域にはHumanクラスのオブジェ
クトのアドレスが入っており、hanakoはそのアドレスを通してオブジェクトを
参照する)には、hanakoのオブジェクトに氏名を教えてもらうためのメッセー
ジは、

hanako.sayName();

という形になります。これを日本語風のメッセージに翻訳?すると

「hanakoさん、sayName( )メソッドを実行してください。」

という感じになります。さらにもっと日本語らしい自然言語のメッセージに
翻訳?すると、

「hanakoさん、氏名を言ってください。」

という感じになります。

これはメッセージの表現でもありますが、「メソッドの呼び出し」という
言い方もします。

つまり、

hanako.sayName();

と書くことを、「hakakoのsayName( )メソッドを呼び出す」というふうに
説明することもあります。

こうして、sayName( ) メソッドを定義しておくと、nameという属性自体は
privateで隠蔽されていても、sayName( )メソッドがpublicなので、
sayName( )メソッドを呼び出すことによって、氏名をディスプレイに表示す
ることができるわけです。

なお、nameはprivateで隠蔽されていても、sayName( )メソッドの中では
使用できます。
これは、nameとsayName( )が同じオブジェクトに属しているからです。

つまり、sayName( )の中では、nameは自分の属性なので自由にアクセスで
きるのです。

このことは、memorizeName( )メソッドについても同じです。


以上でHumanクラスのソース・コードの内容をだいたい理解していただけたと
思いますが、このソース・コードだけでは、たんにHumanクラスが定義された
だけであって、これだけでは、Humanクラスは何もしません。

Humanクラスに何かをさせるためには、Humanクラスのインスタンスにメッ
セージを送るという操作が必要になりますね。

それでは、これからその部分をプログラミングしましょう。

・・・・と言いたいところですが、今回もずいぶん長くなってしまいました
ので、ここで、いったん話を区切ります。


続きは、次回に。



================================================
◆ 02.演習問題
================================================

さきほどのsayName( )メソッドの出力内容を

  My name is Hanako.

のような英語ではなく、

  私の名前は、花子です。

のような日本語にするためには、どうしたらよいでしょうか。
考えてみてください。



┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
★ホームページ:
      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. 不許無断複製