ここまで亀に三角形を描かせるプログラムを使って Java 言語の基本概念を説明しました。以下で は、このプログラムを拡張しながら、ここまでに説明した基本概念をより深く解説します。
2 つのメソッド
先に示した例で、Triangle部品のために定義したメソッドは
main
メソッドを除くとdraw
だけ でした。メソッドはいくつでも定義できるので、リスト 1-3のようにTriangle.java
を修正してメ ソッドを追加することもできます。リスト 1-3 2 つのメソッドを持つプログラム
public class Triangle {
public void draw() {
Turtle t = new Turtle();
t.move(10, 200);
t.penDown();
t.go(100);
t.rotate(120);
t.go(100);
t.rotate(120);
t.go(100);
}
public void drawSmall() { Turtle s = new Turtle();
s.move(200, 200);
s.penDown();
s.go(50);
s.rotate(120);
s.go(50);
s.rotate(120);
s.go(50);
}
public static void main(String[] args) { Triangle tri = new Triangle();
tri.draw();
Lesson1 亀と遊ぼう
tri.drawSmall(); //
追加}
}
小さな三角形を描く
drawSmall
メソッドが追加されました。メソッドを書く順番は自由なので、drawSmall
の後にdraw
メソッドの定義を書いてもかまいません。新しいプログラムでは、mainメ ソッドも修正して、draw
の後にdrawSmall
メソッドを呼ぶようになっているので、このプログラム を実行すると画面に 2 つの三角形が順番に描かれます。drawSmall
メソッドの定義を見ると、Turtleオブジェクトを作成して、sと名前をつけているこ とがわかります。このことを、変数s
にそのオブジェクトを代入する、ともいうことは既に説明し ました。ここでs
と名前をつけられたオブジェクトは、drawメソッドの中でt
と名づけられたオブ ジェクトとは違うものです。オブジェクトはプログラムを構成する部品ですが、1 つのプログラム の中で同じ種類の部品をいくつも使うことができます。上のプログラムの場合、Triangleオブジェ クトを 1 つ、Turtleオブジェクトを 2 つ使っていることになります。実際、画面上でも、亀を表す 黒い丸が 2 つ表示され、2 つの三角形は別々の亀によって描かれます。図 1-9 2 つの三角形
コメント
ところで新しい
main
メソッドの中味にtri.drawSmall(); //
追加とあります。この
//
の後ろから行末までの部分はコメント(comment)または注釈と呼ばれるもので、プログラム中に自由に書き込める説明文です。プログラムをコンパイル/実行するときに、Java の処理系は
//
から行末までを無視します。無視されるので//
から行末までを省略してしまったり、別の説明文に変えても、プログラムの意味は変わりません。コメントはプログラム中のどこにでも 書くことができるので、プログラムを後から読んだときに意味がよくわかるように、補足的な説明 を書くのに使われます。
また、Java では
/*
と*/
で囲まれた部分もコメントと解釈されて処理系が無視します。たとえばtri.drawSmall(/*
引 数 は な い*/);
と書いても、コメント部分が無視されるので
tri.drawSmall();
と同じことになります。
また、/*と
*/
で囲まれたコメントは、途中で改行することもできます。以下はその例です。/*
変 数tri
が 表 す 亀 を 使 っ て 小 さ い 三 角 形 を 描 く*/
tri.drawSmall();
途中で改行されていますが、/*から
*/
までの 3 行はコメントとして無視されます。コメントには何を書いてもよく、プログラムの断片を書くこともできますが、何を書いても無視 されます。ただしコメントの中にコメントを入れ子に書くことはできません。たとえば
/*
注 釈 は/*
と*/
で 囲 ん で 書 く*/
2 回目に出てくる
/*
はコメントの始まりと認識されないので、左側の*/
までがコメントとなりま す。つまり「 で囲んで書く*/」の部分はコメントとして認識されません。
同様に次のコメントも正しいコメントではありません。
//
コ メ ン ト の 中 に/* 2
行 に わ た る コ メ ン ト*/
やはり途中に出てくる
/*
はコメントの始まりと認識されないので、1 行目の行末までがコメントと なります。2 行目の「 …… コメント*/」の部分はコメントとして認識されません。
Java のコメントは
/*
…*/
という形のものか//
から始まる形のものか、2 種類しかないのです が、前者の派生形に/**
…*/
という形のものがあります。これはドキュメンテーションコメン トと呼ばれるもので、プログラムの説明書(ドキュメント)をプログラムの中に埋め込むのに使わ れます。ドキュメンテーションコメントを使ってプログラムの説明を埋め込んでおくと、後で説明 だけを機械的に抽出することができるのでたいへん便利ですが、本書では詳しい説明は割愛します。Lesson1 亀と遊ぼう
クラスと型
これまでの例では、1 つのメソッドの中では 1 つのオブジェクトしか使いませんでしたが、1 つの メソッドの中で複数のオブジェクトを使うこともできます。たとえば
Triangle
部品の定義をリス ト 1-4のように変えてみましょう。リスト 1-4 1 つのメソッドで複数のオブジェクトを使用するプログラム
public class Triangle {
public void drawTwo() { Turtle t1 = new Turtle();
t1.move(10, 200);
t1.penDown();
t1.go(100);
t1.rotate(120);
t1.go(100);
t1.rotate(120);
t1.go(100);
Turtle t2 = new Turtle();
t2.move(30, 190);
t2.penDown();
t2.go(70);
t2.rotate(120);
t2.go(70);
t2.rotate(120);
t2.go(70);
}
public static void main(String[] args) { Triangle tri = new Triangle();
tri.drawTwo();
} }
このプログラムは 2 つの
Turtle
オブジェクトを使って、入れ子になった 2 つの三角形を描きま す(図 1-10)。drawTwo
メソッドは、t1、t2という名前の 2 つのTurtle
オブジェクトを使います。どちらも同じ
Turtle
という種類に属しますが、異なるオブジェクトです。区別のため、Java 言語では、プログラム中で使われる個々の部品のことをオブジェクト、その部品の種類のことをクラス(class)、と いいます。たとえば、ここまでに出てきた
t
やs
という名前のオブジェクトのクラスはTurtle
で す。t1やt2
という名前のオブジェクトのクラスもTurtle
です。一方、triという名前のオブジェ クトのクラスはTriangle
です。図 1-10 入れ子になった三角形
これまで、Triangle部品の定義、などと説明してきましたが、これは正確には
Triangle
クラス の定義というべきなのです。Triangle.javaに保存されているTriangle
の定義は、public class Triangle {
省 略}
という形をしていますが、先頭の
class
は、この定義がTriangle
クラスの定義であることを表し ていたのです。ところで先ほどクラスに似た用語で型という用語が出てきました。どちらも種類を表しますが、
型のほうが広い意味で使われます。Java 言語では、オブジェクトの型のことをとくにクラスと呼ぶ、
と考えればよいでしょう。したがって、オブジェクトのクラスという代わりに、オブジェクトの型 といっても問題ありません。しかし一般に、変数の型とはいいますが、変数のクラスとはいわない ようです。
もう一点、大切なことがあります。今
Turtle
オブジェクトを 2 個使いましたが、それらのオブ ジェクトは一度に片方しか動きません。先のプログラムの順序を変えて、それぞれのオブジェクト のメソッドを交互に呼ぶようにしてみます。public void drawTwo() { Turtle t1 = new Turtle();
t1.move(10, 200);
t1.penDown();
Turtle t2 = new Turtle();
t2.move(30, 190);
Lesson1 亀と遊ぼう
t2.penDown();
t1.go(100);
t1.rotate(120);
t2.go(70);
t2.rotate(120);
t1.go(100);
t1.rotate(120);
t2.go(70);
t2.rotate(120);
t1.go(100);
t2.go(70);
}
このプログラムを実際に動かしてみるとわかりますが、2 匹の亀が同時に動いて三角形を描くこ とにはなりません。一方の亀が動いている間は、他方の亀は停止したままです。Java 言語では、メ ソッドの呼び出しが終了するまで次のステップへ進みません。したがって片方の亀のメソッドが実 行中のときは、他方の亀のメソッドは決して呼ばれることはなく、亀は停止したままです。2 匹の 亀を同時に動かして三角形を描かせるためにはスレッド(thread)と呼ばれる機能を使って、もう少 し複雑なプログラムを書く必要があります(スレッドについては??で解説します)。
変数への代入
drawTwo
メソッドは、t1、t2という名前の 2 つのTurtle
オブジェクトを使いました。実は Java 言語では、同じメソッドの中で、違うオブジェクトに同じ名前をつけることができます。もちろん 違うオブジェクトに同時に同じ名前をつけることはできませんが、メソッドの途中で、それまで別 のオブジェクトにつけられていた名前を違うオブジェクトにつけることができます。public void drawTwo() { Turtle t1 = new Turtle();
t1.move(10, 200);
t1.penDown();
t1.go(100);
t1.rotate(120);
t1.go(100);
t1.rotate(120);
t1.go(100);
t1 = new Turtle(); //
名前のつけかえt1.move(30, 190);
t1.penDown();
t1.go(70);
t1.rotate(120);
t1.go(70);
t1.rotate(120);
t1.go(70);
}
このように
drawTwo
メソッドを書き変えると、t1という名前のオブジェクトはt1 = new Turtle();
より下では、2 つ目の
Turtle
オブジェクトの名前になります。このステップは、新しく作成したTurtle
オブジェクトにt1
という名前をつけろ、という意味です。これは、新しく作成したTurtle
オブジェクト(の参照番号を)を変数t1
に代入しろ、と読むこともできます(図 1-11)。以後、変 数t1
の値は新しく代入された値に変わります。変数t1
は既に使われている変数なのでt1
の前にTurtle
と書く必要はありません。変数は、初めて使われるときにだけ、先頭に型を書きます。逆に最初に変数
t1
が出てきたときには、先頭にTurtle
と書かなければなりません。たとえば、public void drawTwo() {
t1 = new Turtle(); //
先頭にTurtleがないt1.move(10, 200);
以 下 省 略
は誤ったプログラムです。すべての変数は、型が何であるか最初に宣言しなければなりません。
図 1-11 変数への異なるオブジェクトの代入
同じオブジェクトに異なる名前を同時につけることもできます。たとえば