目錄

2022 興大物件導向程式設計 Test1 歷屆題

簡介與查閱說明

此篇文章為 2022 年 4 月 15 日考的物件導向程式設計的考古題。

所有被放在這種區塊的文字都是題目的一部分。

所有被放在這個區塊外面的區塊題目都沒給,是我寫的題解。

更新記錄

  • 2024/04/05:修正了部分拼字錯誤
    • randumNumbersrandomNumbers
    • contructorsconstructors
  • 2024/04/15:其實 Test1 跟 Midterm 是不同的,修正標題為 Test1

Q1

Which of the following promotions of primitive types is not allowed to occur?
a. char to int
b. double to float
c. int to double
d. short to long

A1

答案:(b.)
double 是 64 位的雙精度浮點數,不能被隱式直接提升到 32 位的 float(單精度浮點數)。會有數據損失

1
2
3
4
double d = 1.00000000000001;
float f;
f = d; // 錯誤,不能被隱式轉換
f = (float)d; // 可以通過編譯,但小數點後有部分會無法儲存

在 Java 的基本類型之間進行 promotions (提升) 時有個基本原則:「記憶體空間較小、範圍較小」的數據類型可以自動提升到「記憶體空間較大、範圍較大」的類型。

其它選項:

a. char 在 Java 中是 16 位的無號類型,可以被無損地提升到 32 位的 int 類型
c. int 是 32 位的有號類型,可以被提升到 64 位的 double
d. short 是 16 位的有號整數;long 是 64 位的有號整數

Q2

Which of the following class members should usually be private?
a. Methods.
b. Constructors.
c. Variables (or fields).
d. All of the above.

A2

答案:c. Variables (or fields).

一個程式中的變數 (Variables) 或資料成員 (fields 又稱為 member variable) 在一般情況下應該是 private (也就是不能直接被其它 class 中成員讀取)

舉例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
class Person {
    int age; // member variable
    int weight; // member variable

    Person(int a, int w) { // Constructor
        if(0 <= a && a <= 120) { // 輸入的年齡介於 0 與 120 歲之間
            this.age = a; // 把輸入的年齡存起來
        } else { // 輸入的年齡竟然是負的或是超過 120 歲
            this.age = 18; // 亂填的就當作 18 歲
        }
        this.w = w;
    }

    public void sayMyInfo() { // Methods
        System.out.printf("你好!我已經 %d 歲了,我有 %d 公斤重。", this.age, this.weight);
    }
}

通常我們不會希望其它人可以直接修改一個 Person 物件的 ageweight,因為這樣可能會造成一些不可預測的後果(千年人妖)。在這個例子中,我們會在 Constructor 裡面檢查輸入的年齡有沒有在合理範圍,若超出範圍我們就認定是 18 歲(不錯吧)

看看其它選項:

a. Methods:方法不一定要是 private,如果像例子中的 sayMyInfo 需要給使用者調用,那就會設為 public
b. Constructors:Constructors 是在創造物件時會調用的方法,通常不會設為 private
d. All of the above:因為 (a.) 和 (b.) 不對,所以不能選

Q3

When must a program explicitly use the this reference?
a. Accessing a private variable.
b. Accessing a public variable.
c. Accessing a local variable.
d. Accessing an instance variable that is shadowed by a local variable.

A3

答案:(d.)

如選項所述,this 通常用於當物件的變數被局域變數 (local variable) 隱藏起來的時候。舉個例子:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
class Person {
    int age;
    int weight;
    Person(int age, int weight) {
        this.age = age;
        this.weight = weight; 
    }
}

Person me = new Person(20, 70);

在這個例子中,this.age 代表被創建的物件的變數;而 age 則代表在 Constructor 宣告的 local variable

蛤?你還是不懂?看看示意圖:

/nchu-oop-java-2022-test-1-histo/image.webp

Q4

Having a this reference allows:
a. a method to refer explicitly to the instance variables and other methods of the object on which the method was called.
b. a method to refer implicitly to the instance variables and other methods of the object on which the method was called.
c. an object to refernce itself.
d. All of the above.

A4

答: (d.) All of the above

把題目進行中文翻譯:

擁有 this 這個 reference 允許:

a. 允許 method 可以顯式地 (explicitly) 參考實例變數 (instance variable) 和物件中的其它 method

1
2
3
4
5
6
7
8
class Person {
    int age;
    int weight;
    Person(int age, int weight) {
        this.age = age; // 顯式使用 this.age
        this.weight = weight; // 顯式使用 this.weight
    }
}

b. 允許 method 可以隱式地 (implicitly) 參考實例變數 (instance variable) 和物件中的其它 method

1
2
3
4
5
6
7
8
class Person {
    int age;
    int weight;
    Person(int a, int w) {
        age = a; // 隱式使用 this.age
        weight = w; // 隱式使用 this.weight
    }
}

在 (b.) 中因為沒有 local variable 同樣叫作 ageweight,所以 age 就會自動隱式地乎叫 this.ageweight 就會自動隱式地乎叫 this.weight

c. 允許一個物件參考它自己

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // 判斷當前物件是否和另一個 Person 物件相同
    public boolean equals(Person otherPerson) {
        if (otherPerson == this) { // otherPerson 其實就是目前這個物件(同一個物件)
            return true;
        }
        if (otherPerson == null) {
            return false; // null 值不等於任何物件
        }
        
        // 不同個物件,但可以檢查屬性是不是相同
        // 比較 name 和 age 來判斷是否內容相同
        return this.name.equals(otherPerson.name) && this.age == otherPerson.age;
    }
}

d. 以上皆是

Q5

Constructors:
a. Initialize instance variables.
b. When overloaded, can have identical argument lists.
c. When overloaded, are selected by number, types and order of types of parameters.
d. Both (a) and (c).

A5

答案:(d.) Both (a) and (c)

這題要簡介一下什麼是 overloaded (重載) ,一樣用 Person 作舉例,不過這次多了個身高 height 屬性:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
class Person {
    int age;
    int weight;
    int height;
    Person () { // 什麼都不輸入時
        this.age = 18;
        this.weight = 75;
    }

    Person (int age, int weight) { // 只有輸入年齡、體重時
        this.age = age;
        this.weight = weight;
    }
    Person (int age, int weight, int height) { // 同時輸入年齡、體重、身高時
        this.age = age;
        this.weight = weight;
        this.height = height;
    }
}

上面例子中你可以看到與 Class 名稱相同的 Constructor 多達三個!天啊!這麼多 Constructor,我在宣告物件時 Java 怎麼會知道要用誰呢?

答案就是靠你傳入的變數的數量還有類型

1
2
3
Person jack = new Person(); // 使用無參數的 Constructor
Person jim = new Person(18, 70); // 使用兩個參數的 Constructor
Person jimmy = new Person(18, 70, 180); // 使用三個參數的 Constructor

所以這題的選項:
a. 初始化 instance variable:確實可以
b. 當 overloaded 時,不可以有一樣的參數(如果都是兩個參數,那類型也要不同,總之要能從類型參數數量這兩者判斷出是調用哪個 Constructor
c. 當 overloaded 時,Constructor 會被依據參數數量、類型、類型的順序(eg. 先 String 再 int != 先 int 再 String)選擇。正確

所以選 d. Both (a) and (c).

Q6

When implementing a method, use the class’s set and get access the class’s _______ data.
a. public
b. private
c. protected
d. All of the above.

A6

答案:(b) private

舉例:getter 和 setter 的用法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
class Person {
    private int age;
    public void setAge(int age) { // set method
        if(0 <= age && age <= 120) {
            this.age = age;
        } else {
            System.out.println("我的媽呀,年齡請介於 0 與 120(含)");
        }
    }
    public int getAge() { // get method
        return this.age;
    }
}

可以看到,通常的使用方法是將變數設為 private,然後讓使用者只能透過 setAgegetAge 改變 age 的值。這麼做的好處是可以控管 age 的值,不讓它是 -3 這類不合理的數字。

Q7

Using public set methods helps provide data integrity if:
a. The instance variables are public.
b. The instance variables are private.
c. The methods perform validity checking
d. Both b and c.

A7

答案:(d) Both b and c.

不論是 b 或是 c,透過 setter 設定變數都有助於提供更完整的數據。

透過 A6 中的範例,你可以看到如果我們透過 setter 設定變數的值,就可以確保變數的值一定是我們希望的範圍。所以當 methods 提供 validity checking、instance variables 被設成 private 時,set methods helps provide data integrity.

Q8

Static class variables:
a. are final.
b. are public.
c. are private.
d. are shared by all objects of a class.

A8

答案:d. are shared by all objects of a class

Static 靜態方法代表這個方法 (method) 屬於整個 class,而不是屬於被創件的物件,舉個例子:

1
2
3
4
5
6
7
8
class MathTool {
    static public int staticATimesB(int a, int b) {
        return a * b;
    }
    public int aTimesB(int a, int b) {
        return a * b;
    }
}

在這個例子中,雖然 staticATimesBaTimesB 方法的參數、回傳值都一樣,但是一個有被加上 static 的關鍵字,使用方法就會改變。

static 靜態方法的使用方法是 類名.方法名

1
2
// 印出 6
System.out.println(MathTool.staticATimesB(2, 3));

而非 static 方法的使用方法是 被創建的物件名.方法名

1
2
MathTool tl = new MathTool();
System.out.prinln(tl.staticATimesB(2, 3));

Q9

A constructor cannot:
a. be overloaded
b. initialize variables to their defaults.
c. specify return types or return values.
d. have the same name as the class.

A9

答案:c. specify return types or return values.

a. 選項請參考 A5,當然可以 overloaded
b. 選項也是可以的。
c. 選項:一個 constructor 不會有回傳值,所以當然不能 specify return types or return values.
d. 選項:constructor 的名字一定要跟 class 的名字相等。

Q10

When no access modifier is specified for a method or variable, the method or variable:
a. Is public.
b. Is private.
c. Has package access.
d. Is static.

A10

答案:c. Has package access

題目的意思如下:

1
2
3
4
public int a;
private int b;
protected int c;
int d;

當出現如 d 這種前面沒有 publicprivateprotectedacces modifier 時,想請問 d 的訪問權限到底為何?

在 Java 中有四種訪問權限,分別如下:

  1. public:任何人都可以存取,權限範圍最大
  2. protected:只有這個類別的 子類別 可以存取,權限範圍第二大
  3. (no modifier/預設):在同一個 package 中可以存取,其它套件不行
  4. private:只有自己這個類別的成員可以存取,權限範圍最小
存取修飾 同一類別 同一套件 不同套件的子類別 不同套件的非子類別
private OK
default OK OK
protected OK OK OK
public OK OK OK OK

(Reference: 參考資料一參考資料二 )

Q11

Which statement is true?
a. Dividing two integers results in integer division.
b. With integer division, any fractional part of the calculation is lost.
c. With integer division, any fractional part of the calculation is truncated.
d. All of the above.

A11

答案:d. All of the above.

a. 兩個整數相除會得到整數除法:正確

System.out.println(5/3) 會得到 1 而不是 1.6666...

b. 正確,如 (a.) 中的舉例。

c. 正確,跟 b. 意思差不多

故選 d. All of the above.

Q12

Which of the following is not a Java Keyword?
a. do
b. next
c. while
d. for

A12

答案:b. next

a. do:在 do...while 時會用

1
2
3
do {
    statements;
} while (condition);

b. next

如果認為這個是 Keyword 的人應該是被 SecureRandomScanner 中的 nextInt 搞混了。
nextIntSecureRandomScanner 這些類中的方法 (method),而不是 Java 的保留字。
你可以想想看:如果我沒有 import ScannerSecureRandom,事實上 Java 是認不出 nextInt 的對吧?況且 nextInt 也跟 next 不一樣。

c. while:在 while 迴圈時會用

1
2
3
while(condition) {
    statements;
}

d. for:在 for 迴圈時會用

1
2
3
for(int i = 0; i < 10; i++) {
    System.out.println("助教好帥可以給我分數嗎");
}

Q13

Which of the following methods are overloaded with respect to one another?

1
2
3
4
public int max (int a, int b) { ... }
public int double max (double a, double b) { ... }
public int max (int a, int b, int c) { ... }
public double max (double a, double b, double c) { ... }

a. A and B are overloaded; C and D are overloaded.
b. A and C are overloaded; B and D are overloaded.
c. A, B and C are overloaded.
d. All four methods are overloaded.

A13

答案:d. All four methods are overloaded.

你可以看到 A, B, C 和 D 四種 method 的名稱都一樣,都是 max。而且透過它們的參數和數量/類型可以彼此辨別。(可參考 A5)

Q14

boolean values can be displayed as the words true and false with the _______ format specifier.
a. %bool
b. %b
c. %true
d. %boolean

A14

答案:b. %b

就…背起來吧

Q15

To exit out of a loop completely, and resume the flow of control at the next statement after the loop, use a ______.
a. continue statement
b. break statement
c. return statement
d. Any of the above

A15

答案:b. break statement

a. continue:進入「下一圈迴圈」

1
2
3
4
5
6
for(int i = 0; i < 10; i++) {
    if(i % 2 == 0) {
        continue;
    }
    System.out.println(i);
}

這個程式會印出 1, 3, 5, 7, 9。
因為每個偶數都會符合 i % 2 == 0,然後 continue 進到下一圈,而不印出數字。

b. break:如題目所述,會跳出整個迴圈

c. return:會回傳值,讓整個方法都結束

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class MathTool {
    static int calculateAPlusToB(int a, int b) { // 計算 a 加到 b
        int sum = 0;
        for(int i = a; i <= b; i++) {
            sum += i;
            if(i == b) {
                return sum;
            }
        }
        System.out.println("我最喜歡 Java 了")
    }
}

在以上這個例子中,當我們呼叫 MathTool(1, 10),程式會在 i == 10 的時候回傳 1 加到 10 的總和。因為已經 return,整個 method 已經結束,所以就不會出印出 "我最喜歡 Java 了",沒辦法向教授傳達我們對 Java 的喜愛之情,真是可惜呀!

Q16

Which of the following for-loop headers results in equivalent numbers of iterations:

1
2
3
4
A. for (int q = 1; q <= 100; q++)  
B. for (int q = 100; q >= 0; q--)
C. for (int q = 99; q > 0; q -= 9)
D. for (int q = 990; q > 0; q -= 90)

a. A and B.
b. C and D.
c. A and B have equivalent iterations and C and D have equivalent iterations.
d. None of the loops have equivalent iterations.

A16

答案:(b). C and D.

A. q 從 1 到 100,共 100 次
B. q 從 100 到 0,共 101 次
C. q 從 99 到 9,以 9 為間隔,共 11 次
D. q 從 990 到 90,以 90 為間隔,共 11 次

如果用程式驗證,大致長這樣:

1
2
3
4
5
6
7
8
9
public class MainApp {
	public static void main(String args[]) {
		int sum = 0;
		for(int q = 990; q > 0; q -= 90) {
			sum++;
		}
		System.out.println(sum);
	}
}

Q17

Which of the following promotions of primitive types is not allowed to occur?
a. char to int
b. double to float
c. int to double
d. short to long

A17

這題跟 Q1 一 模 一 樣
答案為 b. double to float

Q18

Reference-type variables (called references) store ________ in memory.
a. the value of an object.
b. a copy of an object
c. the location of an object.
d. the size of an object.

A18

答案:c. the location of an object.

Reference 又叫作參考,是儲存物件的記憶體位址。有點像是代稱。

比如講 Q4 中的 this 就是一種 Reference,儲存了目前這個物件本身的記憶體位址,所以我們可以用 this 代表(代稱)目前這個物件。

Q19

Which statement creates a random value from the sequence 2, 5, 8, 11 and 14. Suppose randomNumbers is a SecureRandom object.
a. 2 + 5 * randomNumbers.nextInt(3);
b. 3 + 2 * randomNumbers.nextInt(5);
c. 5 + 3 * randomNumbers.nextInt(2);
d. 2 + 3 * randomNumbers.nextInt(5);

A19

答案:d. 2 + 3 * randomNumbers.nextInt(5);

要解此題需要以下兩點:

  1. 在程式中同樣有先乘除後加減的優先順序
  2. randomNumbers.nextInt(n); 會產生 0, 1, 2, 3, ..., n-1 範圍的隨機數(不包括 n 自身)

所以像 d. 2 + 3 * randomNumbers.nextInt(5);

  • randomNumbers(5) 產生 0, 1, 2, 3, 4 中的隨機數
  • 3 * randomNumbers(5) 使序列變成 0, 3, 6, 9, 12
  • 2 + 3 * randomNumbers.nextInt(5); 使序列變成 2, 5, 8, 11, 14 即為所求。

Q20

Which set of statement totals the values in two-dimensional int array items?

a.

1
2
3
4
int total = 0;
for(int subItems : items)
    for(int item : subItems)
        total += item;

b.

1
2
3
int total = 0;
for(int item : int[] subItems : items)
    total += item;

c.

1
2
3
4
int total = 0;
for(int[] subItems : items) 
    for(int item : items)
        total += item;

d.

1
2
3
4
int total = 0;
for(int[] subItems : items)
    for(int item : subItems)
        total += item;

A20

答案: d.

因為題目說了 items 是一個二維的 (two-dimensional) array。
換句話說: items 是一個陣列,它的每一個元素都是一個一維陣列 int[]

/nchu-oop-java-2022-test-1-histo/image_of_items_and_item.webp

所以第一層 for 迴圈會從 items 中取出每一個元素,每個元素都是一個一維的陣列 int[],我們讓它的名字是 subItems

1
for(int[] subItems : item)

第二層 for 迴圈會從一維陣列 subItems 中取出每一個元素,每個元素都是一個 int,我們讓它的名字是 item

1
2
for(int[] subItems : item)
    for(int item : subItems)

最後我們用一個 sum 把所有值加起來:

1
2
3
4
int total = 0;
for(int[] subItems : items)
    for(int item : subItems)
        total += item;

就得到了 d. 選項

(手寫題)Answer the following Questions

接下來的題目重新編號了,看起來應該是手寫題。

Q1 (手寫)

Give the method header for each of the following methods.

a) Method hypotenuse, which takes two double-precision, floating-point arguments side1 and side2 and returns a double-precision, floating-point result.

b) Method smallest, which takes three integers x, y, and z and returns an integer.

c) Method instructions, which does not take any arguments and does not return a value. [Note: Such methods are commonly used to display instructions to a user.]

d) Method intToFloat, which takes an integer argument number and returns a floating-point result.

A1 (手寫)

答案:
a. double hypotenuse(double side1, double side2)
b. int smallest(int x, int y, int z)
c. void instructions()
d. float intToFloat(int number)

解題重點:

1
回傳類型 方法名稱(參數類型1 參數名稱1, 參數類型2 參數名稱2, ...)

(沒有回傳值的話類型是 void,沒有參數的話則是 () 內留空)

Q2 (手寫)

Write statements that could be used to simulate the outputs of tossing a quarter to get heads or tails? Suppose randomNumbers is a SecureRandom object.

A2 (手寫)

答案:randomNumbers.nextInt(2)

因為 SecureRandom 中的 nextInt(n) 會從 0, 1, 2, ..., n-1(不包括 n)的數列中取隨機數,所以欲產生 0, 1 隨機數要用 randomNumbers.nextInt(2)

Q3 (手寫)

Write statements that will display a random number from each of the following sets: 2, 4, 6, 8, 10

A3 (手寫)

答案:
System.out.println(2 + randomNumbers.nextInt(5) * 2)

因為 randomNumbers.nextInt(5) 會以 0, 1, 2, 3, 4 這個序列生成隨機數。

我們將其 * 2,得到:
0, 2, 4, 6, 8 這個序列

再將其加上 2,得到:
2, 4, 6, 8, 10

故答案為:
System.out.println(2 + randomNumbers.nextInt(5) * 2)

Q4 (手寫)

Determine whether each of the following is true or false. If false, explain why.

a) To refer to a particular location or element within an array, we specify the name of the array and the value of the particular element.

b) An array declaration reserves space for the array.

c) To indicate that 100 locations should be reserved for integer array p, you write the delcaration p[100];

A4 (手寫)

a. False
原因:要取 array 中的特定元素或位置需要 array 的名稱和 index(而不是值 value)

b. False
原因:在 Java 中宣告 array 並不會為它保留空間。只有當你使用 new 創建 array 時,才會為其保留空間。

1
2
int[] numbers; // 宣告了一個 Reference,但沒有創建物件、也沒有分配記憶體空間
int[] numbers = new int[5]; // 有創件物件並保留空間

c. False
正確的寫法如下:

1
int p[] = new int[100];

Q5 (手寫)

Consider a two-by-three integer array t.

a) Write a statement that declares and creates t.

b) Write access expressions for all the elements in row 1 of t.

c) Write access expressions for all the elements in column 2 of t.

d) Write a nested for statement that initializes each element of t to zero.

e) Write a nested for statement that inputs the values for the elements of t from the user.

f) Write a series of statements that determines and displays the smallest value in t.

A5 (手寫)

a.

1
int t[][] = new int[2][3];

b.

1
t[1][0], t[1][1], t[1][2]

c.

1
t[0][2], t[1][2]

d.

1
2
3
4
5
for(int j = 0; j < t.length; j++) {
    for(int k = 0; k < t[j].length; k++) {
        t[j][k] = 0;
    }
}

e.

1
2
3
4
5
for(int j = 0; j < t.length; j++) {
    for(int k = 0; k < t[j].length; k++) {
        t[j][k] = input.nextInt();
    }
}

f.

1
2
3
4
5
6
7
8
9
int smallest = t[0][0];
for(int j = 0; j < t.length; j++) {
    for(int k = 0; k < t[j].length; k++) {
        if(t[x][y] < smallest) {
            smallest = t[x][y];
        }
    }
}
System.out.println(smallest);