オブジェクト指向言語・期末テスト問題用紙（2018 年 08 月 03 日・ 10:30 〜 12:00）

解答上、その他の注意事項

I. 問題は、問 I〜V まである。うち、問 I〜II は中間試験の代替問題である。
II. 解答用紙の右上の欄に学籍番号・名前を記入すること。
III. 解答欄を間違えないよう注意すること。
IV. 解答中の文字 (特に a と d) がはっきりと区別できるよう注意すること。
V. 持ち込みは不可である。筆記用具・時計・学生証以外のものは、かばんの中などにしまうこと。
VI. テストの配点は 70 点（うち中間試験の代替問題の問 I〜II の配点は 30 点）である。合格はレポートの得点を加点して、100 点満点中 60 点以上とする。

すべての問に対する補足:
プログラムの空欄を埋める問題では、解答が長くなる可能性があるので、下の省略形（を用いても良い。（必ず で囲むこと。）

囲み文字）

  A ActionListener aA addActionListener AE ActionEvent  K KeyListener aK addKeyListener KE KeyEvent  M MouseListener aM addMouseListener ME MouseEventpl System.out.println
pf System.out.printf

また、参考のために問題用紙の末尾に授業配布プリントの LeftRightButton3.java, LeftRightButton4.java,Guruguru.java, Point.java, ColorPoint.java のソースを掲載する。

1

I. 次の枠内の文章は java.awt.Rectangle クラスのいくつかのメソッドと、java.lang.Math ク
ラスの random メソッドの JavaTM API 仕様からの抜粋（問題を解くのに関係ない部分は割愛）である。
java.awtクラス Rectangle
Rectangle は、座標空間内の長方形オブジェクトの左上の点 (x,y)、その幅、およびその高さで囲まれた座標空間内の領域を指定します。 . . .
フィールドの詳細
public int x
Rectangle の左上隅の X 座標。
public int y
Rectangle の左上隅の Y 座標。
public int width
Rectangle の幅。
public int height
Rectangle の高さ。
コンストラクターの詳細
public Rectangle(int x, int y, int width, int height)
左上隅が (x,y) として指定され、幅と高さが width 引数と height 引数によって指定される新しい Rectangle を構築します。
パラメーター:x - 指定された X 座標
y - 指定された Y 座標
width - Rectangle の幅。
height - Rectangle の高さ。
メソッドの詳細
public Rectangle intersection(Rectangle r)
この Rectangle と指定された Rectangle の共通部分を計算します。2 つの長方形の共通部分を表す新しい Rectangle を返します。2 つの長方形が交差しない場合、空の長方形が返されます。
パラメーター:r - 指定された Rectangle
戻り値:
指 定 さ れ た Rectangle と こ の Rectangle の 両 方 に 収 ま る 最 大 のRectangle、これらの長方形が交差しない場合は空の長方形。

public Rectangle union(Rectangle r)2

この Rectangle と指定された Rectangle の和集合を計算します。2 つの長方形の和集合を表す新しい Rectangle を返します。 . . .
パラメーター:r - 指定された Rectangle
戻り値:指定された Rectangle とこの Rectangle の両方を含む最小の Rectangle。

java.lang
クラス Math
Math クラスは、指数関数、対数関数、平方根、および三角関数といった基本的な数値処理を実行するためのメソッドを含んでいます。 . . .
メソッドの詳細
public static double random()
0.0 以上で 1.0 より小さい、正の符号の付いた double 値を返します。戻り値は、この範囲からの一様分布によって擬似乱数的に選択されます。. . .
戻り値:

0.0 以上 1.0 未満の擬似乱数 double。
これらのメソッドを使用するプログラムを次のように作成する。
ファイル名: RectangleTest.java

1234567891011121314151617181920212223

import java.awt.Color;
import java.awt.*;
import javax.swing.*;
public class RectangleTest extends JPanel {private int width = 320, height = 320;
public RectangleTest() {setPreferredSize(new Dimension(width, height));}
private Rectangle randomRect(int min, int w, int h) {(i-1));
int rw = (int)(int rh = (int)((i-2));
int rx = (int)((i-3));
int ry = (int)((i-4));
return new Rectangle(rx, ry, rw, rh);}@Override
protected void paintComponent(Graphics g) {super.paintComponent(g);Rectangle rect1 = randomRect(50, width, height);

3

24
25
26
2728
2930
31
32
33
34
35
36
37

Rectangle rect2 = randomRect(50, width, height);
Rectangle union =(ii);g.setColor(Color.BLUE);
g.fillRect(union.x, union.y, union.width, union.height);
g.setColor(Color.GREEN);
g.fillRect(rect1.x, rect1.y, rect1.width, rect1.height);
g.setColor(Color.YELLOW);
g.fillRect(rect2.x, rect2.y, rect2.width, rect2.height);
Rectangle isect =(iii);g.setColor(Color.RED);g.fillRect(isect.x, isect.y, isect.width, isect.height);}/* main メソッドは割愛 */このプログラムは、再描画ごとに乱数で座標が決まる 2 つの長方形を緑 (green) と黄 (yellow) で描画し、さらに、2 つの長方形の両方を含む最小の長方形を青 (blue) で、2 つの長方形の両方に収まる最大の長方形を赤で描画する。

• 空欄 (i-1)〜(i-4) には、4 つの式が入る。(i-1) は min 以上 w 未満の乱数、(i-2) は min 以上 h未満の乱数、(i-3) は 0 以上 (w - rw) 未満の乱数、(i-4) は 0 以上 (h - rh) 未満の乱数、を返す式が入る。Math クラスの random メソッドを使って、この空欄を埋めよ。（解答欄には、(i-1) と (i-3) のみ記入せよ。）• 空欄 (ii) には、rect1 と rect2 の両方を含む最小の Rectangle を返す式が入る。この空欄を埋めよ。
• 空欄 (iii) には、rect1 と rect2 の両方に収まる最大の Rectangle を返す式が入る。この空欄を埋めよ。
II. フォントの見本を表示するために、次のプログラム（FontTester クラス）を GUI アプリケーションとして作成する。これはテキストフィールドを 2 つ持ち、最初は、“Hello, World!” という文字列を、サイズ 16 の Times New Roman フォントで表示していて、• 「Name:」というラベルの付いているほうのテキストフィールドに文字列を入力すると、その文字列から始まるフォント名をフォント名の一覧 (fontList) から検索して、表示されている文字列のフォントの種類を変更する。
• 「Size:」というラベルの付いているほうのテキストフィールドに整数を入力すると、表示されている文字列のフォントのサイズを変更する。という Java プログラムである。
ファイル名: FontTester.java

123
45

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class FontTester extends JPanel implements ActionListener {4678910111213141516171819202122232425262728
2930
3132
33
3435
36
37
38
3940
41
42
43
4445
46
47
48
49
50
51
52
53
54

String fontName = "Times␣New␣Roman";int fontSize = 16;
Font font = new Font(fontName, Font.PLAIN, fontSize);
String[] fontList = { "Times␣New␣Roman", "Courier␣New", "Arial" };JTextField nameTF, sizeTF;
public FontTester() {setPreferredSize(new Dimension(320, 80));
nameTF = new JTextField("Times␣New␣Roman", 16);
sizeTF = new JTextField("16", 3);add(new JLabel("Name:")); add(nameTF); add(new JLabel("Size:")); add(sizeTF);
(i-1)
(i-2)
}
private String selectFont(String init) {for (String s: fontList) {if (s.toLowerCase().startsWith(init.toLowerCase())) return s;}
return Font.SERIF;}
public void actionPerformed(ActionEvent e) {Object target = e.getSource();if (target == nameTF) {fontName = selectFont(nameTF.getText());} else if (target == sizeTF) {fontSize = Integer.parseInt(sizeTF.getText());}
font = new Font(fontName, Font.PLAIN, fontSize);
repaint();}@Override
protected void paintComponent(Graphics g) {super.paintComponent(g);g.setFont(font);
g.drawString("Hello,␣World!", 16, 64);}
public static void main(String[] args) {SwingUtilities.invokeLater(() -> {JFrame frame = new JFrame("");
frame.add(new FontTester());
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
});
}

5

55 }

(i) 空欄 (i-1)〜(i-2) にはあわせて 2 つの文が入る。この空欄を埋めよ。
さらにこの FontTester.java を匿名クラス・ラムダ式を用いて次のように同等のプログラム
FontTester2.java に書き換える。
ファイル名: FontTester2.java

12345678910111213141516171819202122232425

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class FontTester2(ii)String fontName = "Times␣New␣Roman";int fontSize = 16;
Font font = new Font(fontName, Font.PLAIN, fontSize);
String[] fontList = { "Times␣New␣Roman", "Courier␣New", "Arial" };JTextField nameTF, sizeTF;{

public FontTester2() {setPreferredSize(new Dimension(320, 80));
nameTF = new JTextField("Times␣New␣Roman", 16);
sizeTF = new JTextField("16", 3);add(new JLabel("Name:")); add(nameTF); add(new JLabel("Size:")); add(sizeTF);
nameTF.addActionListener((iii));
sizeTF.addActionListener((iv));}/* selectFont, paintComponent, main メソッドは割愛 */}• 空欄 (ii) を埋めよ。
• 空 欄 (iii), (iv) を 埋 め て 、FontTester2 の コ ン ス ト ラ ク タ ー の 定 義 を 完 成 さ せ よ 。
た だ し 、空欄 (iii) に は 匿 名 ク ラ ス を 、空欄 (iv) に は ラ ム ダ 式 を 使 用 せ よ 。適 宜 、/* FontTester.java の○〜△行目と同じ */ のように省略してよい。

III. 以下の選択問題に答えよ。解答は次の選択肢から選べ。
(A). Java(B). Haskell(C). C(D). Prolog(i) 論理型言語に分類される言語はどれか? 一つを選べ。
(ii) 命令型（手続き型）言語に分類される言語はどれか? 一つを選べ。

6

IV. 次に定義されるクラス Fish を継承して、ファイル名: Fish.java
1 public class Fish {2protected int age;3
public void grow() { age++; }4public void showName() { System.out.print("サカナ␣"); }5
public void growShowName() { showName(); grow(); }6 }3 つのクラス Carp, Seriola, Mugil を定義する。
ファイル名: Carp.java

1 public class Carp(i)2public String color;3
public Carp(String c) { color = c; }4
5@Override
6
public void showName() {7if (age < 1000) {8System.out.print(color + "鯉␣");9} else {10System.out.print(color + "龍␣");
11}
12}
13 }

{

ファイル名: Seriola.java

1 public class Seriola
2@Override3
public void showName() {4if (age == 0) {5System.out.print("ツバス␣");6} else if (age <= 2) {7System.out.print("ハマチ␣");8} else {9System.out.print("ブリ␣");
10}
11}
12 }

(i)

{

ファイル名: Mugil.java

1 public class Mugil
2@Override
3
public void showName() {4if (age <= 1) {5System.out.print("オボコ␣");6} else {(i)7{7System.out.print("ボラ␣");
8}
9}
10 }
また、FishTest クラスはこれらのクラスのテスト用の main メソッドを持つ。
ファイル名: FishTest.java

1 public class FishTest {2
public static void main(String[] args) {3
Carp c = new Carp("緋");4c.color = "金";5Fish[] fish = { c, new Seriola(), new Mugil() };67int i, j;
8for (i = 0; i < 3; i++) {9for (j = 0; j < 3; j++) {10fish[j].growShowName();11}
12System.out.println();// 改行を出力
13}14for (i = 0; i < 998; i++) {15for (j = 0; j < 3; j++) {16fish[j].grow();
17}
18}
19for (j = 0; j < 3; j++) {20fish[j].showName();21}// 改行を出力
22
System.out.println();
23}
24 }

(i) の空欄（3 箇所で共通）を埋めて、クラスの定義を完成させよ。
(ii) Carp クラスのフィールド color の値はコンストラクターでのみ与えることができるものとし、一旦作成した後は、クラスの外からは直接アクセスできないようにしたい。（例えば、FishTest.java の 4 行目はコンパイル時にエラーになるようにしたい。）
Carp.java の何行めをどのように変更すれば良いか？（行の左端の数字がファイルの中での行数を表す。）(iii) FishTest.java の 4 行目をコメントアウトし、このクラスの main メソッドを実行するとき、出力はどうなるか？ （ただし、Fish クラスおよびそのサブクラスのインスタンスが新しく生成されたときのフィールド age の初期値は 0 である。）解答用紙に記入するとき、空白の有無や数は気にしなくて良い。

8

V. 下のプログラムは、アニメーションを表示する Java GUI アプリケーションである。
ファイル: TraﬃcLight.java

1 import java.awt.*;
2 import javax.swing.*;3
4 public class TrafficLight extends JPanel
5
private int state = 2;
6private volatile Thread thrd = null;
7
8
private Color changeColor(Color c, int s) {9if (state == s) return c;
10
return Color.DARK_GRAY;
11}
12
13
public TrafficLight() {14setPreferredSize(new Dimension(300, 150));
15
JButton startBtn = new JButton("start");
16
startBtn.addActionListener((ii)
17JButton stopBtn = new JButton("stop");18
stopBtn.addActionListener((iii)19
JButton nextBtn = new JButton("next");(iv)
20
nextBtn.addActionListener(
21add(startBtn); add(stopBtn); add(nextBtn);
22}
23
24
private void startAnimation() {25if (thrd == null) {(v);26thrd =
27
thrd.start();
28}
29}
30
31
private void stopAnimation() {32thrd = null;
33}
34
35
public void next() {36state++;37
state %= 3;38
repaint();
39}
40
41
@Override42
protected void paintComponent(Graphics g) {super.paintComponent(g);4344g.setColor(changeColor(Color.GREEN, 0));45
g.fillOval(10, 60, 80, 80);46
g.setColor(changeColor(Color.YELLOW, 1));
47
g.fillOval(110, 60, 80, 80);9(i));););{

48
g.setColor(changeColor(Color.RED, 2));49
g.fillOval(210, 60, 80, 80);
50}
51
52
public void run() {53
Thread me = Thread.currentThread();54
while ((vi)) {55
next();56
try {57
Thread.sleep(1500); // 1.5 秒お休み
58
} catch (InterruptedException e) {}
59}
60}
61
62
public static void main(String[] args) {63
SwingUtilities.invokeLater(() -> {64
JFrame frame = new JFrame("");
65
frame.add(new TrafficLight());
66
frame.pack();
67
frame.setVisible(true);
68
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
69});
70}
71 }
このプログラムは、緑、黄、赤の 3 つの色に対応する円を描画し、“start” というボタンをクリッ
クすると、アニメーションを開始して、約 1.5 秒ごとに、緑 → 黄 → 赤→ 緑、の順に色がつく円を切り換える（他の円は灰色にする）。“stop” というボタンをクリックすると、このアニメーションを停止する。“next” というボタンをクリックしても（アニメーションの実行中かどうかにかかわらず）、緑 → 黄 → 赤 → 緑、の順に色を切り換える。

(i)〜(vi) の空欄を埋めてプログラムを完成させよ。

10

以下に参考のために授業配布プリントの LeftRightButton3.java, LeftRightButton4.java, Guruguru.java,Point.java, ColorPoint.java のソースを掲載する。
LeftRightButton3.java<import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class LeftRightButton3 extends JPanel {private int x = 20;
public LeftRightButton3() {setPreferredSize(new Dimension(200, 70));
JButton lBtn = new JButton("Left");
JButton rBtn = new JButton("Right");lBtn.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {x -= 10;repaint();}});
rBtn.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {x += 10;repaint();}});
setLayout(new FlowLayout());
add(lBtn); add(rBtn);}@Override
public void paintComponent(Graphics g) {super.paintComponent(g);g.drawString("HELLO␣WORLD!", x, 55);}/* main メソッドは割愛 */}LeftRightButton4.java
import javax.swing.*;
import java.awt.*;
public class LeftRightButton4 extends JPanel {private int x = 20;
public LeftRightButton4() {setPreferredSize(new Dimension(200, 70));
JButton lBtn = new JButton("Left");
JButton rBtn = new JButton("Right");lBtn.addActionListener(e -> {x -= 10;repaint();});
rBtn.addActionListener(e -> {x += 10;repaint();});
setLayout(new FlowLayout());
add(lBtn); add(rBtn);}@Override
public void paintComponent(Graphics g) {11super.paintComponent(g);g.drawString("HELLO␣WORLD!", x, 55);}/* main メソッドは割愛 */}Guruguru.java
import java.awt.*;
import javax.swing.*;
public class Guruguru extends JPanel implements Runnable {private int r = 50, x = 110, y = 70;
private double theta = 0; // 角度
private volatile Thread thread = null;public Guruguru() {setPreferredSize(new Dimension(200, 180));
JButton startBtn = new JButton("start");startBtn.addActionListener(e -> startThread());
JButton stopBtn = new JButton("stop");
stopBtn.addActionListener(e -> stopThread());
setLayout(new FlowLayout());
add(startBtn); add(stopBtn);
startThread();}private void startThread() {if (thread == null) {thread = new Thread(this);thread.start();}}private void stopThread() {thread = null;}@Overridepublic void paintComponent(Graphics g) {super.paintComponent(g); // スーパークラスの paintComponent を呼び出す// 全体を背景色で塗りつぶす。
g.drawString("Hello,␣World!", x, y);}public void run() {Thread thisThread = Thread.currentThread();for (; thread == thisThread; theta += 0.02) {x = 60 + (int)(r * Math.cos(theta)); y = 100 - (int)(r * Math.sin(theta));repaint(); // paintComponent を間接的に呼出す
try {Thread.sleep(30); // 30 ミリ秒お休み} catch (InterruptedException e) {}}}/* main メソッドは割愛 */}Point.java
public class Point {public int x, y;
public void move(int dx, int dy) {12x += dx;

y += dy;}
public double distance() {return Math.sqrt(x * x + y * y);}public void print() {System.out.printf("(%d,␣%d)", x, y);}public void moveAndPrint(int dx, int dy) {print(); move(dx, dy); print();}
public Point(int x0, int y0) {x = x0; y = y0;}}

ColorPoint.java
public class ColorPoint extends Point {private String[] cs = {"black", "red", "green", ..., "white"};private String color;@Override
public void print() {System.out.printf("<font␣color=’%s’>", getColor());
super.print();
System.out.print("</font>");}public void setColor(String c) {int i;for (i = 0; i < cs.length; i++) {if (c.equals(cs[i])) {color = c; return;}} // 対応する色がなかったら何もしない。
}
public ColorPoint(int x, int y, String c) {super(x, y);setColor(c);if (color == null) color = "black";}
public String getColor() { return color; }}13// 色の指定// 色を戻すRectangleTest.java のスクリーンンショット

FontTester.java のスクリーンンショット

TraﬃcLight.java のスクリーンンショット−→
1.5 秒
または“next”−→
1.5 秒
または“next”

14オブジェクト指向言語・期末テスト解答用紙（2018 年 08 月 03 日）

学籍番号

氏名

（4, 4, 4）I.
(i-1).
(i-3).
(ii).
(iii).

（4, 4, 5, 5）II.
(i-1).
(i-2)(ii).
(iii).

nameTF.addActionListener(匿名クラス);(iv).

sizeTF.addActionListener(ラムダ式);

（3 × 2）

III.
(i).

(ii).
（4, 6, 6）

IV.
(i).
(ii).

(iii).

（3 × 6）V.
(i).
(ii).
(iii).
(iv).
(v).
(vi).
授業・テストの感想.................................................................................................
.................................................................................................
.................................................................................................
.................................................................................................
.................................................................................................
.................................................................................................
.................................................................................................
.................................................................................................
.................................................................................................