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

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

I. 問題は、問 I〜VII まである。うち、問 I〜III は中間テストの代替問題である。
(i) 各大問（I, II, III）ごとに、中間テストの得点が 6 割に達しなかったものは、対応する代替問題の大問を解答すれば、6 割を上限として良いほうの点数を採用する。
(ii) 事情があって中間テストを欠席した者も代替問題を解答すること。（この場合は、上限は設けない。）
II. 解答用紙の右上の欄に学籍番号・名前を記入すること。
III. 解答欄を間違えないよう注意すること。
IV. 解答中の文字 (特に a と d) がはっきりと区別できるよう注意すること。
V. 持ち込みは不可である。筆記用具・時計・学生証以外のものは、かばんの中などにしまうこと。
VI. テストの配点は 80 点（うち中間テストの代替問題の問 I〜III の配点は 40 点）である。
合格はレポートの得点を加点して、100 点満点中 60 点以上とする。

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

囲み文字）

  A ActionListener aA addActionListener AE ActionEvent  KKeyListener
aKaddKeyListener
KEKeyEvent    M MouseListener aM addMouseListener ME MouseEventpl System.out.println
pf System.out.printf

また、参考のために問題用紙の末尾に授業配布プリントの MouseTest.java, LeftRightButton.java, LeftRightButton3.java, LeftRightButton4.java, Guruguru.java, Point.java, ColorPoint.java のソースを掲載する。（main メソッドは省略している。）

1

I. 次の各多肢選択問題に答えよ。解答は各問の指示する選択肢から選べ。ただし、特に指定しない限り、選ぶべき選択肢は必ずしも 一つとは限らない。
(i) 文法上 Java のクラス名として使うことができるのは、どれか?
(A). M-1 (B). 2000percent(C). Off_White(D). NMB48(ii) Java で要素の型が double[] 型であるような ArrayList 型の変数 xs を宣言したい。正しい書き方を 1 つ、以下の選択肢から選べ。
(A).
(B).
(C).
(D).

ArrayList<double[]> xs = new ArrayList<>();
double[]<ArrayList> xs = new double[]<>();
ArrayList[double<>] xs = new ArrayList[]();
double<ArrayList[]> xs = new double<>();

II. 次の枠内の文章は java.awt.event.MouseEvent クラスの getClickCount メソッドと、java.
lang.Math クラスの atan2 メソッドの JavaTM API 仕様からの抜粋（問題を解くのに関係ない部分は割愛）である。
java.awt.event
クラス MouseEvent
コンポーネント内でマウスアクションが発生したことを示すイベントです。. . .
メソッドの詳細
public int getClickCount()
このイベントに関連付けられたマウスクリック数を返します。
戻り値:
クリック数を表す整数値

java.lang
クラス MathMath クラスは、指数関数、対数関数、平方根、および三角関数といった基本的な数値処理を実行するためのメソッドを含んでいます。. . .
メソッドの詳細
public static double atan2(double y, double x)
直交座標 (x, y) から極座標 (r, theta) への変換から得られる角度 theta を返します。このメソッドは、-pi – pi の範囲で y/x の逆正接 (アーク・タンジェント) を計算することで、位相 theta (シータ) を計算します。. . .
パラメータ:

y - 縦座標x - 横座標2

戻り値:
直交座標 (デカルト座標) 上の点 (x, y) に対応する極座標上の点 (r, theta) の、
theta (シータ) 成分。
これらのメソッドを使用するプログラムを次のように作成する。
ファイル名: MouseTrainer.java

12345678910111213141516
171819202122232425262728
2930
3132
333435

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MouseTrainer extends JPanelprivate int count = 0;
private static final double t1 = 43 * Math.PI / 180,t2 = 47 * Math.PI / 180;(i){// 43 度// 47 度public MouseTrainer() {setPreferredSize(new Dimension(128, 128));
addMouseListener(this);}@Override
protected void paintComponent(Graphics g) {super.paintComponent(g);// 目安となる線分を描く
g.drawLine(0, 0, (int)(172 * Math.cos(t1)), (int)(172 * Math.sin(t1)));g.drawLine(0, 0, (int)(172 * Math.cos(t2)), (int)(172 * Math.sin(t2)));g.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 24));g.drawString(count + "回", 64, 32);// 回数を表示する}
public void mouseClicked(MouseEvent e) {int x = e.getX(), y = e.getY();
double theta =(ii);if (t1 <= theta && theta <= t2 &&count++;
repaint();
}
}

(iii)

>= 2) {/* 他の MouseListener のメソッドと main メソッドは割愛 */}このプログラムは、原点 (0, 0) とマウスをクリックした点 (x, y) を結ぶ線分と x 軸のなす角が43 度以上 47 度以下でかつダブルクリックのとき（クリック数が 2 以上のとき）に、回数をインクリメントしそれを表示する。

3

実行例は次のようになる。

2 回ダブルクリックしたとき

さらに 3 回ダブルクリックしたとき• 空欄 (i) を埋めよ。
• 空欄 (ii) には、原点 (0, 0) とマウスをクリックした点 (x, y) を結ぶ線分と x 軸のなす角を求める式が入る。この空欄を埋めよ。
• 空欄 (iii) には、マウスのクリック数を求める式が入る。この空欄を埋めよ。
III. 漸化式
xn+1 = 48271 × xn mod 2147483647に基づく擬似乱数列を表示するために、次のプログラム（RandomTester クラス）を GUI アプリケーションとして作成する。これはボタンを 1 つとテキストフィールドを 1 つ持ち、最初は1 という整数をテキストフィールドに表示していて、• ボタンをクリックすると、現在テキストフィールドに表示している整数から、漸化式に基づき次の乱数を計算して、テキストフィールドに表示する。
• テキストフィールドに整数を入力すると、その数を次の乱数の “種” として設定する。という Java プログラムである。
実行例は次のようになる。

数回クリックしたときある整数を入力して数回クリックしたとき

ファイル名: RandomTester.java

123
45678910111213

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class RandomTester extends JPanel implements ActionListener {private long x = 1;
private JButton button;
private JTextField field;
public RandomTester() {button = new JButton("Next");(i)field = new JTextField("1", 10);4

14field.setHorizontalAlignment(JTextField.RIGHT); // 右詰めにする(ii)
15
16add(button); add(field);
17}
1819
public void actionPerformed(ActionEvent ev) {20Object source =(iii);
21if (source == button) {22x = 48271 * x % 2147483647;
23
field.setText("" + x);24} else if (source == field) {25try {
26x = Integer.parseInt(field.getText());
27} catch (NumberFormatException ex) {}28
field.setText("" + x);
29}
3031}
3233/* main メソッドは割愛 */34 }• 空欄 (i)〜(iii) を埋めよ。
さらにこの RandomTester.java を匿名クラス・ラムダ式を用いて次のように同等のプログラム
RandomTester2.java に書き換える。
ファイル名: RandomTester2.java

1234567891011121314151617181920

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class RandomTester2
private long x = 1;(iv)

public RandomTester2() {JButton button = new JButton("Next");
JTextField field = new JTextField("1", 10);
button.addActionListener((v));
field.setHorizontalAlignment(JTextField.RIGHT);
field.addActionListener((vi));
add(button); add(field);}5{

2122/* main メソッドは割愛 */23 }• 空欄 (iv) を埋めよ。
• 空 欄 (v), (vi) を 埋 め て 、RandomTester2 の コ ン ス ト ラ ク タ ー の 定 義 を 完 成 さ せよ。ただし、空欄 (v) には匿名クラスを、空欄 (vi) にはラムダ式を使用せよ。適宜、/* RandomTester.java の○〜△行目と同じ */ のように省略してよい。

【中間テストの代替問題はここまで】

IV. 以下の選択問題に答えよ。解答は次の選択肢から選べ。
(A). Java(B). COBOL(C). Haskell(D). Prolog(i) この中で関数型言語に分類される言語はどれか? 一つを選べ。
(ii) この中で最も古くからある言語はどれか? 一つを選べ。
V. 次の Python のリスト内包表記の値は何か?
(i) [x * y for x in [1,3,7] for y in [2,5]](ii) [x for x in [2,3,4] if x * x % 3 == 1]

6VI. 次に定義されるクラス animals.Animal を継承して、ファイル名: animals/Animal.java
1 package animals;
2 public class Animal {3protected int age;4
public Animal() { age = 0; }5public void say() {6System.out.print("...");
7age++;8}9 }3 つのクラス animals.Dog, animals.Cat, animals.Pheasant を定義する。
ファイル名: animals/Dog.java

1 package animals;
2 public class Dog
3public Dog() { super(); }4@Override
5
public void say() {6if (age < 1) {7System.out.print("Kyan␣");8} else {9System.out.print("Wan␣");
10}11age++;
12}
13 }

(i)

{(i)

{

ファイル名: animals/Cat.java

1 package animals;
2 public class Cat
3public Cat() { super(); }4@Override
5
public void say() {6System.out.print("Nyaa␣" );7age++;
8}
9 }ファイル名: animals/Pheasant.java

1 package animals;
2 public class Pheasant(i)3
private boolean female; // false -- 雄, true -- 雌
4public Pheasant(boolean f) { super(); female = f; }5@Override
6
public void say() {7{7if (age < 1) {8System.out.print("Piii␣");9} else if (female) {10System.out.print("Chocho␣");11} else {12System.out.print("Keeen␣");13}
14age++;15}
16 }
また、（匿名パッケージの）AnimalTest クラスはこれらのクラスのテスト用の main メソッドを持つ。
ファイル名: AnimalTest.java

1 public class AnimalTest {2
public static void foo(Animal a) {3
int i;
4for(i = 0; i < 3; i++) {5a.say(); System.out.print("\t");6}
7System.out.println();8}910
public static void main(String[] args) {11Dog d = new Dog();12Cat c = new Cat();
13Pheasant p = new Pheasant(false);
14p.female = true;// Dog, Cat, Pheasant
15
16foo(d); foo(c); foo(p);
17}
18 }

(i) の空欄（3 箇所で共通）を埋めて、クラスの定義を完成させよ。
(ii) animals.Pheasant クラスのフィールド female の値はクラスの外からは直接アクセスできないため、AnimalTest.java の 14 行目はコンパイル時にエラーになるはずである。デバッ
グのため、一時的にこれをエラーにならないようにしたい。
animals.Pheasant クラスのフィールド female の可視性を変えて AnimalTest.java の 14行目がエラーにならないようにするためには、animals/Pheasant.java の何行めをどのように変更すれば良いか？（行の左端の数字がファイルの中での行数を表す。）(iii) AnimalTest.java の 14 行目がエラーにならないように animals/Pheasant.java を変更し、AnimalTest クラスの main メソッドを実行するとき、出力はどうなるか？
なお、解答用紙に記入するとき、空白の有無や数は気にしなくて良い。

8

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

1 import java.awt.*;
2 import javax.swing.*;3
4 public class ClockSimulator extends JPanel(i)
5private int min = 0;
6
private volatile Thread thread = null;
7
private final static int cx = 100, cy = 140; // 中心の座標
89public ClockSimulator() {10setPreferredSize(new Dimension(200, 240));
11JButton toggleBtn = new JButton("start/stop");12
toggleBtn.addActionListener(e ->(ii));13
add(toggleBtn);
14
toggleThread();
15}
16
17
private void toggleThread() {18
if (thread == null) {19
thread = new Thread(this);
(iii)
;
20
21} else {22(iv);
23}
24}
25
26
@Override27
public void paintComponent(Graphics g) {28
super.paintComponent(g);29
int m = min % 60;
30
double tm = m / 30.0 * Math.PI; // 長針は 60 分で一周
31
double x = Math.sin(tm), y = -Math.cos(tm);32g.drawLine(cx, cy, cx + (int)(100 * x), cy + (int)(100 * y));33
int h = min % 720;
34
double th = h / 360.0 * Math.PI; // 短針は 720 分で一周
35
x = Math.sin(th); y = -Math.cos(th);36
g.drawLine(cx, cy, cx + (int)(80 * x), cy + (int)(80 * y));
37}
38
39
public void run() {40
Thread me = Thread.currentThread();
(v)
) {
41
while (42min++;43
repaint(); // paintComponent を間接的に呼出す
44
try {
45
Thread.sleep(100);46} catch (InterruptedException e) {}
47}
9{

48}
4950
/* main メソッドは割愛 */51 }このプログラムは、時計をシミュレートする。ただし、約 100 ミリ秒ごとに 1 分進む。また“start/stop” というボタンをクリックするごとに、アニメーションの実行・停止を切り替える。
実行例は次のようになる。

数秒経過したとき

さらに数秒経過したとき(i)〜(v) の空欄を埋めてプログラムを完成させよ。

10

以下に参考のために授業配布プリントの MouseTest.java, LeftRightButton.java, LeftRightButton3.java,LeftRightButton4.java, Guruguru.java, Point.java, ColorPoint.java のソースを掲載する。
MouseTest.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class MouseTest extends JPanel implements MouseListener {private int x = 50, y = 20;
public MouseTest() {setPreferredSize(new Dimension(150, 150));
addMouseListener(this);}public void mouseClicked(MouseEvent e) {x = e.getX(); y = e.getY();
repaint();}
public void mousePressed(MouseEvent e) {}public void mouseReleased(MouseEvent e) {}public void mouseEntered(MouseEvent e) {}public void mouseExited(MouseEvent e) {}@Override
public void paintComponent(Graphics g) {super.paintComponent(g);g.drawString("HELLO␣WORLD!", x, y);}/* main メソッドは割愛 */}LeftRightButton.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class LeftRightButton extends JPanel implements ActionListener {private int x = 20;
private JButton lBtn, rBtn;
public LeftRightButton() {setPreferredSize(new Dimension(200, 70));lBtn = new JButton("Left");rBtn = new JButton("Right");lBtn.addActionListener(this);rBtn.addActionListener(this);
setLayout(new FlowLayout());
add(lBtn); add(rBtn);}@Override
public void paintComponent(Graphics g) {super.paintComponent(g);g.drawString("HELLO␣WORLD!", x, 55);}
public void actionPerformed(ActionEvent e) {Object source = e.getSource();if (source == lBtn) {// lBtn が押された
x -= 10;11

} else if (source == rBtn) { // rBtn が押された
x += 10;}
repaint();}/* main メソッドは割愛 */}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();});

12

setLayout(new FlowLayout());
add(lBtn); add(rBtn);}@Override
public void paintComponent(Graphics g) {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;}@Override
public 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 メソッドは割愛 */}13

Point.java
public class Point {public int x, y;
public void move(int dx, int dy) {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; }}14// 色の指定// 色を戻す

このページは計算用紙に使用しても良い。
【冊子から切り離しても良い。】

15

このページは計算用紙に使用しても良い。
【冊子から切り離しても良い。】

16

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

学籍番号

氏名

（3 × 2）

I.
(i).

(ii).
（4, 6, 6）

II.
(i).
(ii).
(iii).

（1, 1, 3, 3, 5, 5）

III.
(i).
(ii).
(iii).
(iv).
(v).

button.addActionListener(匿名クラス);(vi).

field.addActionListener(ラムダ式);

（3 × 2）

IV.
(i).

(ii).
（3 × 2）

V.
(i).
(ii).

（3, 5, 5）

VI.
(i).
(ii).

(iii).

（3 × 5）

VII.
(i).
(ii).
(iii).
(iv).
(v).
授業・テストの感想.................................................................................................
.................................................................................................
.................................................................................................
.................................................................................................
.................................................................................................
.................................................................................................
.................................................................................................