レコード ( record ) とは、(関連性のある)いくつかのデータをひとまとめにしたものです。 次の図はレコードのイメージを表しています。
レコードの構成要素を フィールド ( field ) とよびます。
以前、データをまとめたものとして配列を取り上げました。 配列とレコードには次のような違いがあります。
int
[]などと規則的に決まりますが、レコード型の名前は個別に決めます。
ここで、レコード型とは、レコードを表すデータ型です。
レコード型は、データ型としての名前、フィールドの名前、およびそれぞれのフィールドのデータ型で定義されます。
上記のイメージの場合は、データ型としての名前をTime, フィールドの名前を
hour
と
minute
, フィールドのデータ型を整数型(
int
型)と定義します。
実は、Javaにはレコードはありません。 しかし、 インスタンス ( instance ) というものがレコードの機能を持っています。 レコードとインスタンスの対応は次の通りです。
一般 | Java |
---|---|
レコード | インスタンス |
フィールド | インスタンス変数 |
レコード型 | クラス |
この授業では、インスタンス、フィールド、およびクラスという用語を用います。
ちなみに、プログラミング言語によっては、レコードのことを構造体とよびます。
レコードとしてのインスタンスを使うには、まず、クラスを定義します。
フィールドのデータ型が整数型(
int
型)なら、クラスの定義は次のようになります。
class クラス { int フィールド1; ...; int フィールドn; }
ここで、「 クラス 」はクラス名、「 フィールド 」はフィールド名です。 上記の例なら、次の通りです。
/* 1*/ class Time { // クラス名 /* 2*/ int hour; // フィールド名 /* 3*/ int minute; // フィールド名 /* 4*/ }
これをファイルTime.javaに保存します。 このファイルがないと、以下のプログラムは動きません。
クラスが定義できたら、プログラムを作成します。 次のプログラムは、変数を宣言し、インスタンスを生成してそこに格納し、インスタンスのフィールドにデータを格納し、その値を表示するものです。
/* 1*/ class TimeTest { // Timeクラスのテスト /* 2*/ public static void main (String[] args) { /* 3*/ Time x; // 宣言 /* 4*/ x = new Time(); // 生成 /* 5*/ x.hour = 9; // hourフィールドに格納 /* 6*/ x.minute = 30; // minuteフィールドに格納 /* 7*/ System.out.println(x.hour + ":" + x.minute); // フィールドの値を出力 /* 8*/ } /* 9*/ }
asiaa1:~/comp2b k12x1001$ java TimeTest 9:30 asiaa1:~/comp2b k12x1001$
変数に整数(
int
型)を格納するには、変数の宣言が必要でした。
変数にインスタンスを格納するにも、同様に変数の宣言が必要です。
これは次のように書きます。
クラス 変数;
今まで
int
と書いていた部分をクラス名に変えます。
3行目で、変数
x
をTimeクラスと宣言します。
クラスのインスタンスは、明示的に生成してはじめて使えます。
インスタンスを生成するには、キーワード
new
を用います。
「
クラス
」のインスタンスを生成して、「
変数
」に格納するには、
変数 = new クラス();
と書きます。 4行目で、Timeクラスのインスタンスを生成して、変数 x に格納します。
なお、次のように書くと、変数の宣言とインスタンスの生成、そしてその変数への格納が同時に行えます。
クラス 変数 = new クラス();
インスタンスのフィールドにデータを格納するには、次のような文を用います。
変数.フィールド = 式;
これで、「 変数 」に格納されているインスタンスの「 フィールド 」に、「 式 」の値が格納されます。 5行目で、インスタンス x の hour フィールドに9が格納され、6行目で、 minute フィールドに30が格納されます。
インスタンスのフィールドに格納されたデータを取り出すには、式
変数.フィールド
を用います。 この式の値は、「 変数 」に格納されているインスタンスの「 フィールド 」に格納されているデータです。 7行目で、インスタンス x の hour フィールドと minute フィールドからデータを取り出して、出力します。
クラスのインスタンスを扱う場合、これまでは、インスタンスを生成してからフィールドに値を格納しました。 例えば次のように書きました。
Time x = new Time(); x.hour = 13; x.minute = 15;
配列では、初期化を使ってプログラムを短くしました。 インスタンスでも、 コンストラクタ ( constructor )というものを用いると、初期化に相当することができます。 上記の例なら、例えば次のように書けます。
Time x = new Time(13, 15);
もし、クラスが
class クラス { int フィールド1; ...; int フィールドn; }
と定義されていたら、次のように定義し直すと、コンストラクタが使えるようになります。
class クラス { int フィールド1; ...; int フィールドn; クラス (int フィールド1, ..., int フィールドn) { this.フィールド1 = フィールド1; ... this.フィールドn = フィールドn; } }
これで、式
new クラス(引数1, ..., 引数n)
を呼び出すと、「 フィールド 1 」に「 引数 1 」を格納し、…、「 フィールド n 」に「 引数 n 」を格納したインスタンスになります。
コンストラクタはメソッドに似ています。 どちらも、あらかじめ定義しておき、呼出しによってその機能が働きます。 メソッドとコンストラクタは以下の点が異なります。
void
や
int
などと書いて返り値の型を指定しました。
コンストラクタ定義では、返り値の型は指定しません。
new
とクラス名を書きます。
次のプログラムでは、コンストラクタも定義したクラスTime2を定義しています。 Time2.java の4行目から7行目までが、コンストラクタ定義です。 このコンストラクタは、第1引数を hour フィールドに格納し、第2引数を minute フィールドに格納します。 Time2Test.java の3行目で、このコンストラクタが呼び出され、 hour フィールドに9が格納され、 minute フィールドに30が格納されます。
/* 1*/ class Time2 { // 時刻2 /* 2*/ int hour; /* 3*/ int minute; /* 4*/ Time2 (int hour, int minute) { // コンストラクタ定義 /* 5*/ this.hour = hour; /* 6*/ this.minute = minute; /* 7*/ } /* 8*/ }
/* 1*/ class Time2Test { // Time2クラスのテスト /* 2*/ public static void main (String[] args) { /* 3*/ Time2 x = new Time2(9, 30); // コンストラクタ呼出し /* 4*/ System.out.println(x.hour + ":" + x.minute); /* 5*/ } /* 6*/ }
asiaa1:~/comp2b k12x1001$ java Time2Test 9:30 asiaa1:~/comp2b k12x1001$
注意1. 上記のコンストラクタは、「典型的なコンストラクタ」と呼ぶべきものです。 一般的には、コンストラクタはより複雑な機能を持ちます。
注意2.
上記のようにコンストラクタを定義すると、
new Time2()
ではインスタンスが生成できなくなります。
実は、コンストラクタを定義しなければ引数なしのコンストラクタが自動的に用意され、コンストラクタを定義すると定義したものだけが使えるという規則になっています。
引数ありと引数なしの両方のコンストラクタを使うには、次のように両方定義します。
class Time3 { int hour; int minute; Time3 () { } Time3 (int hour, int minute) { this.hour = hour; this.minute = minute; } }
インスタンスの例として、以前考えた買い物の問題を再び取り上げます。
A子は店に行き、150円のペットボトルを1本と120円の缶ジュースを3本買いました。 A子はいくら支払わなければならないでしょうか。
/* 1*/ class SomeDrinks2 { // いくつかの飲み物2 /* 2*/ public static void main (String[] args) { /* 3*/ int total, pet = 150, can = 120; /* 4*/ total = pet + 3 * can; /* 5*/ System.out.println(total); /* 6*/ } /* 7*/ }
このプログラムでは、値段だけを変数に格納し、個数は変数に格納しませんでした。 インスタンスを利用すれば、値段と個数をまとめて格納できます。
ファイルBuy.javaでは、買った物を格納するために、Buyというクラスを定義します。 price というフィールドには値段を格納し、 count というフィールドには個数を格納します。
/* 1*/ class Buy { // 買った物 /* 2*/ int price; // 値段 /* 3*/ int count; // 個数 /* 4*/ }
ファイルBuyMain.javaでは、Buyクラスの変数 pet を宣言し、Buyクラスのインスタンスを生成して pet に格納します。 変数 can についても同様に宣言・生成します。 インスタンス pet にはペットボトルの値段と個数を格納し、インスタンス can には缶ジュースの値段と個数を格納します。 最後に、合計金額を計算します。
/* 1*/ class BuyMain { // 買った物のメイン /* 2*/ public static void main (String[] args) { /* 3*/ int total; /* 4*/ Buy pet = new Buy(); // 宣言と生成 /* 5*/ Buy can = new Buy(); // 宣言と生成 /* 6*/ pet.price = 150; // ペットボトルの値段は150円 /* 7*/ pet.count = 1; // ペットボトルの個数は1個 /* 8*/ can.price = 120; // 缶ジュースの値段は120円 /* 9*/ can.count = 3; // 缶ジュースの個数は3個 /* 10*/ total = pet.count * pet.price + can.count * can.price; /* 11*/ System.out.println(total); /* 12*/ } /* 13*/ }
asiaa1:~/comp2b k12x1001$ java BuyMain 510 asiaa1:~/comp2b k12x1001$
続いて、コンストラクタを利用して、このプログラムを短くします。
ファイルBuy2.javaでは、クラスBuy2を定義します。 このクラスのコンストラクタは、引数が値段、個数の順になるように定義します。
/* 1*/ class Buy2 { // 買った物2 /* 2*/ int price; /* 3*/ int count; /* 4*/ Buy2 (int price, int count) { // コンストラクタ定義 /* 5*/ this.price = price; /* 6*/ this.count = count; /* 7*/ } /* 8*/ }
ファイルBuy2Main.javaでは、コンストラクタを呼び出して、Buy2クラスの変数 pet にペットボトルの値段と個数を格納します。 同様に、Buy2クラスの変数 can に缶ジュースの値段と個数を格納します。 最後に、合計金額を計算します。
/* 1*/ class Buy2Main { // 買った物2のメイン /* 2*/ public static void main (String[] args) { /* 3*/ int total; /* 4*/ Buy2 pet = new Buy2(150, 1); // コンストラクタ呼出し /* 5*/ Buy2 can = new Buy2(120, 3); // コンストラクタ呼出し /* 6*/ total = pet.count * pet.price + can.count * can.price; /* 7*/ System.out.println(total); /* 8*/ } /* 9*/ }
asiaa1:~/comp2b k12x1001$ java Buy2Main 510 asiaa1:~/comp2b k12x1001$
来週の授業中に、授業評価のアンケートを実施します。 アンケートはマークシート方式なので、鉛筆かシャープペンシルを持参してください。
シラバスに書いた通り、来週の授業中に試験を行います。 来週は欠席しないようにしてください。
来週の試験は、授業の教室で、授業の後半の30分間で実施します。 試験の方法は筆記試験で、資料の持ち込みやパソコンの利用は不可とします。
以下に練習問題(全20問)を載せますので、試験勉強の参考にしてください。 この問題はレポート課題ではないので、回答を提出する必要はありません。
問1. Javaで割り算はどの記号で表されるか。 以下の中から最も適切なものを選びなさい。
/
:
-
div
問2.
Javaで、文
System.out.println(1 + 2 * 3);
を実行すると何が出力されるか。
以下の中から最も適切なものを選びなさい。
1 + 2 * 3
3 * 3
7
9
問3.
Javaで、実数(浮動小数点数)
1.0E-3
はどの値を表すか。
以下の中から最も適切なものを選びなさい。
問4. Javaで、実数(浮動小数点数)を格納できる変数 x を宣言するにはどう書けばよいか。 以下の中から最も適切なものを選びなさい。
integer x;
int x;
double precision x;
double x;
問5.
Javaで、文
if (x < 0) { System.out.println("負の数"); }
はどう動くか。
以下の中から最も適切なものを選びなさい。
問6. Javaで、変数 x と y に対して「 x と y は等しい」という条件を書くにはどうすればよいか。 以下の中から最も適切なものを選びなさい。
x == y
x = y
x >< y
x <> y
問7. Javaで、変数 x に対して「 x は20以上かつ60未満」という条件を書くにはどうすればよいか。 以下の中から最も適切なものを選びなさい。
20 <= x || x < 60
20 <= x < 60
20 <= x && x < 60
20 <= x, x < 60
問8.
Javaの
if
文で、条件が成り立たない場合を意味するキーワードは何か。
以下の中から最も適切なものを選びなさい。
and
or
else
default
問9.
Javaの
switch
文で、どれでもない場合を意味するキーワードは何か。
以下の中から最も適切なものを選びなさい。
else
default
and
or
問10.
Javaで、
x
が整数型の変数のとき、文
x = x + 1;
は何を意味するか。
以下の中から最も適切なものを選びなさい。
問11.
Javaで、
x
が整数型の変数のとき、文
x--;
は何を意味するか。
以下の中から最も適切なものを選びなさい。
問12.
Javaで、文
for (i = 0; i < 10; i++) { System.out.println(i); }
はどう動くか。
以下の中から最も適切なものを選びなさい。
問13. Javaで、繰返しを途中で終了するにはどの文を使うとよいか。 以下の中から最も適切なものを選びなさい。
while
文
break
文
for
文
switch
文
問14.
Javaで、文
int[] a = new int[10];
を実行すると、どの範囲の配列要素が生成されるか。
以下の中から最も適切なものを選びなさい。
問15.
Javaで、配列を
int[] a = {10, 20, 30, 40};
と初期化すると、式
a
[1]の値は何か。
以下の中から最も適切なものを選びなさい。
問16.
Javaで、配列
a
の要素数を表す式は何か。
以下の中から最も適切なものを選びなさい。
a.number
a.length
a.count
a.size
問17. Javaで、改行を出力するメソッド newline を定義するにはどう書くか。 以下の中から最も適切なものを選びなさい。
static void newline { System.out.println(); }
static void newline () { System.out.println(); }
static int newline { System.out.println(); }
static int newline () { System.out.println(); }
問18. Javaで、改行を出力するメソッド newline を呼び出して、改行を出力するにはどう書くか。 以下の中から最も適切なものを選びなさい。
newline;
newline();
call newline;
call newline();
問19. Javaで、2つの引数の和を返すメソッド add を定義するにはどう書くか。 以下の中から最も適切なものを選びなさい。
static int add (int x, y) { x + y; }
static int add (int x, y) { return x + y; }
static int add (int x, int y) { x + y; }
static int add (int x, int y) { return x + y; }
問20. Javaで、2つの引数の和を返すメソッド add を呼び出して、10と20の和を求めるにはどう書くか。 以下の中から最も適切なものを選びなさい。
add(int 10, 20)
add(10, int 20)
add(10, 20)
add(int 10, int 20)
ある小学校で国語と算数の試験が行われました。 太郎君は国語が70点、算数が80点でした。 花子さんは国語が90点、算数が100点でした。 インスタンスを利用して、これらの得点データを格納し、全体の平均点を計算してください。
asiaa1:~/comp2b k12x1001$ java ScoreMain 85.0 asiaa1:~/comp2b k12x1001$
Score.javaでは、試験の得点を格納するするために、クラスScoreを定義します。 フィールド japanese には国語の得点を格納し、フィールド arithmetic には算数の得点を格納します。
ScoreMain.javaでは、Scoreクラスの変数 taro と hanako を宣言・生成します。 インスタンス taro には太郎君の得点を格納し、インスタンス hanako には花子さんの得点を格納します。 最後に、すべての得点を合計し、4.0で割ります。
余力のある人は、Score2.javaで、コンストラクタも定義したクラスScore2を定義してください。
Score2Main.javaでは、コンストラクタを呼び出して、Score2クラスの変数 taro には太郎君の得点を格納し、Score2クラスの変数 hanako には花子さんの得点を格納します。 最後に、すべての得点を合計し、4.0で割ります。
asiaa1:~/comp2b k12x1001$ java Score2Main 85.0 asiaa1:~/comp2b k12x1001$
今日の演習13の答案(Javaプログラム)をメールで提出してください。 差出人は学内のメール・アドレス(k12x1001@cis.twcu.ac.jpなど)とし、宛先はkonishi@cis.twcu.ac.jpとします。 メールの本文には、学生番号、氏名、科目名、授業日(7月13日)を明記してください。