2023 興大物件導向程式設計期中考歷屆題
前言
希望你在閱讀這是考古題詳解的時候,並不只是「知道」正確答案是什麼。有時候我們也能從其它錯誤選項學到一些重要觀念。
我在撰寫本篇時,會盡可能把每個選項都做解釋,若發現題目、詳解有任何錯誤也請不吝指教。祝大家考試順利。
簡介、查閱說明與更新記錄
此篇文章為 2023 年 4 月 28 日考的物件導向程式設計的考古題。
- 2024/04/16:發佈文章
- 2024/04/21:
- 補全
Q16
中對equals
的解釋。 Q1
:taht
→that
。
- 補全
Q1
Given the java statement
int number1 = input.nextInt();
in which input is Scanner, which of the following occurs if the user does not enter a valid int value?a. A complication error occurs.
b. The program continues executing and assigns the value 0 to number1.
c. A runtime logic error occurs.
d. None of the above
A1
正解:c. A runtime logic error occurs.
詳解:
a. A complication error occurs.
因為題目說 input
已經是一個 Scanner
物件,所以 int number1 = input.nextInt();
並沒有語法上的錯誤,也可以通過編譯。
b. The program continues executing and assigns the value 0 to number1.
c. A runtime logic error occurs.
Java 並不會在使用者亂輸入時直接回傳 input.nextInt()
為 0
,而是會報錯。(如果只要亂輸入就回傳 0 而不報錯,出現 bug 時會很難處理)
我們把 b 跟 c 兩個選項放在一起看。因為我們在編譯階段並不會知道使用者會輸入一個 invalid 的 int value,所以很顯然要執行程式時才能得知。
當 Java 在執行時 (runtime) 發現使用者沒有輸入有效的 int 值,會報錯,所以答案是 c。
Q2
Java requires a _________ call for every object that’s created.
a. constructor
b. destructor
c. parameterless
d. parameterized
A2
正解:a. constructor
Java 在創建物件 (object) 的時候會呼叫該 class 的建構子 (constructor)。
其它選項:
b. destructor
仔細觀察 destructor
,會發現它跟正解 constructor
長得很像。而且 de-
字根的開頭似乎暗示我們它跟 constructor
是反義。
事實上 destructor
的中文是解構子
,正好是建構子
(constructor
) 的相反。如果 constructor
會在物件被創建時被呼叫,那麼我們可以很合理的猜測 destructor
會在物件被銷毀時被呼叫。
在某些程式語言中(像是 C++)當我們使用完記憶體中的物件時需要手動釋放它。這時就要手動呼叫 destructor
。
不過在 Java 中因為在存在垃圾回收器 (Garbage Collector,簡稱 GC),所以我們並不能手動銷毀物件。物件會在使用結束時被自動銷毀。
c. parameterless
這是指沒有參數的 constructor
,在 Java 中如果你不定義任何 constructor
,編譯器會自動提供一個無參數的默認 constructor
。但如果你至少定義了一個 constructor
,就不會有默認 constructor
了。
d. parameterized
這是指帶有參數的 constructor
。
Q3
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
A3
正解:c. the location of an object
Reference-type variables(參考類型的變數)儲存的是對象的記憶體位置。
舉個例子:
|
|
在這個例子中,myDog
是一個參考類型的變數,它儲存的是一個 Dog
類型物件的位置。當 new Dog("Ruby")
被調用時,它在記憶體中創建了一個 Dog
類型的實例,並且 myDog
儲存了這個物件的參考。
也就是說 myDog
儲存的是一個物件的記憶體位置。任何對 myDog
物件的操作實際上都是在對它儲存的記憶體位置間接操作。
如圖,myDog
實際上儲存的是記憶體的位置,在那個記憶體位置你可以找到我們創建完的 Dog
物件。
Q4
Which of the following code segments does not increment val by 3:
a.
val += 3;
b.
|
|
c.
|
|
d. All of the above increment
val
by 3.
A4
正解:c 選項
詳解:
a.
val += 3;
這裡用到了 +=
這個運算子,val += 3
等效 val = val + 3
。所以它有把 val
變為原值加上 3
。
b.
|
|
每一行 val = val + 1;
都會把 val
變為原值加上 1
。因為共有三行,所以最終 val
會是原值加上 3
。
c.
|
|
這裡用到了一個三元運算子,它可以用來做一些簡單的判斷,以下舉例:
|
|
因為這個選項有先宣告一個 c
,並且賦值為 3
。所以很顯然 c == 3
的值是 True
。
所以 c == 3 ? 2 : 3
會回傳 2
。
|
|
故 val
會變為原值加 2
,而不是原值加 3
,故選 c.
Q5
What is the size in bits of an
int
?a. 8
b. 16
c. 32
d. 64
A5
正解:c. 32
在 Java 中,int
的大小是 4
個 bytes
,一個 byte 等於八個 bits,故 int
的大小是 32 bits
,故選 c.
Q6
To exit out of a loop completely, and resume the flow of control at the next state ment after the loop, use a _______.
A6
這題跟 2022 年 Test1 第 15 題一模一樣,傳送門點我 。
正解:b. break
statement
詳解:
a. continue
:進入「下一圈迴圈」
|
|
這個程式會印出 1, 3, 5, 7, 9。
因為每個偶數都會符合 i % 2 == 0
,然後 continue
進到下一圈,而不印出數字。
b. break
:如題目所述,會跳出整個迴圈
c. return
:會回傳值,讓整個方法都結束
|
|
在以上這個例子中,當我們呼叫 MathTool(1, 10)
,程式會在 i == 10
的時候回傳 1 加到 10 的總和。因為已經 return
,整個 method 已經結束,所以就不會出印出 "我最喜歡線性代數了"
。
Q7
boolean values can be displayed as the words
true
andfalse
with the _________ format specifier.a.
%bool
b.%b
c.%true
d.%boolean
A7
這題跟 2022 年 Test1 第 14 題一模一樣,傳送門點我 。
正解:b. %b
詳解:背起來就對了
Q8
Any field declared with keyword _________ is constants.
a. Static
b. const
c. constant
d. final
A8
正解:d. final
詳解:
a. Static
當變數或方法前面出現 Static
,就代表這個變數/方法是屬於整個 class
,而非單一個物件。
|
|
在這個例子中,雖然 staticATimesB
跟 aTimesB
方法的參數、回傳值都一樣,但是一個有被加上 static
的關鍵字,使用方法就會改變。
static
靜態方法的使用方法是類名.方法名
:
|
|
而非 static
方法的使用方法是被創建的物件名.方法名
:
|
|
b. const
這是個誤導選項。const
在其它程式語言(例如 C/C++)中常用來宣告常數。但在 Java 中並沒有這個關鍵字,Java 是用 final
關鍵字來宣告常數。
c.
constant
這和 b 選項一樣也不是 Java 的關鍵字,這只是一個普通的英文單字,意思是「常數、不變的值」。
d.
final
這是正解,在 Java 中想要宣告一個不變的值時,我們會在前面加上 final
。你可以這樣記憶:「既然已經是最後一次修改 (final
) 了,這個變數就不會再變了。」
Q9
Overloaded methods always have the same ________.
a. method name
b. return type
c. number of parameters
d. order of the parameters
A9
正解:a. method name
關於重載 (overload) 的用法,先前在 2022 年 Test1 第 5 題也有提及過,傳送門點我 。
詳解:
在重載的時候,method 的名稱一定是一樣的(不然怎麼叫 “重載” 呢?名稱若不同,就是不同的方法而已)
舉例說明 Overload 的用法:
|
|
上面例子中你可以看到與 Class
名稱相同的 Constructor
多達三個!天啊!這麼多 Constructor
,我在宣告物件時 Java 怎麼會知道要用誰呢?
答案就是靠你傳入的變數的數量
還有類型
。
|
|
Q10
A set of named constants that start with the value 0 for the first constant and increment by 1 for each subsequent constant can be declared as a(n) ________.
a.
class
b.enum
c.enumeration
d. None of the above.
A10
正解:b. enum
詳解:
事實上我認為題目中的 start with the value 0 for the first constant and increment by 1 for each subsequent constant
有誤導的問題。我會在 b 選項的詳解中提到這一點。
a.
class
class
用來定義類。在 Java 中一個類可以包含變數、方法、建構子等,但它並不是這題的最佳答案。
b.
enum
在 Java 中,enum
是一種特殊的類型,用來宣告一組具名的常數,舉例:
|
|
當我們宣告出 Day
這個 enum
之後,我們就可以很明確的用 Day.MONDAY
代表禮拜一、Day.TUESDAY
代表禮拜二…。這可以增加程式的可讀性,讓程式更好維護管理。
你可能此時會想:
喔 ~ enum 是這樣用啊…但…題目說的 value start from 0… 哪來的 value??
我認為題目想問的可能是序數,也就是順序。我們可以用 .ordinal()
方法取得某個 enum
中的某個常量的順序是第幾個:
|
|
這是我對題目的理解,我有可能是錯的。若有人知道題目真正所指的意思是什麼,可以在下方留言為我指點迷津。但目前就我的理解,題目出得不太好。
c.
enumeration
這個選項跟 b 看起來很像,但 enumeration
並不是 Java 的一個關鍵字。這個單詞的意義是「枚舉」。可以說是小小的誘答選項。
Q11
Which expression adds 1 to the element of array
arrayName
at indexi
?a.
++arrayName[i]
b.arrayName++[i]
c.arrayName[i++]
d.None of the above
A11
正解:a. ++arrayName[i]
詳解:
a.
++arrayName[i]
++
運算子的使用方式:
|
|
++
運算子放在變數的前方或後方,影響的是他在一條 statement
中的優先順序,但是當我們單獨把 x++
或 ++x
寫成一行則沒有影響。(同一條 statement 中只有它自己,沒有優先順序的問題)
|
|
所以 a 選項等效於:
|
|
b.
arrayName++[i]
語法錯誤
c.
arrayName[i++]
會先取得 arrayName[i]
的值,然後讓 i = i + 1
:
|
|
Q12
An exception object’s ________ method returns the exception’s error message.
a. String
b. Message
c. Error
d. toString
A12
正解:d. toString
在許多程式語言中(包括 Java 和 JavaScript)當發生異常時,會建立一個異常物件(exception object)來封裝有關錯誤的資訊。
異常物件通常會包含各種屬性,其中之一是描述異常的錯誤訊息。異常物件的 toString
方法負責以字串的型式回傳錯誤訊息。故答案為 d 選項。
Q13
Which of the following tasks cannot be performed using an enhanced for loop?
a. Calculating the product of all the values in an array.
b. Displaying all even element values in an array.
c. Comparing the elements in an array to a specific value.
d. Incrementing the value stored in each element of the array.
A13
正解:d. Incrementing the value stored in each element of the array.
詳解:
要解這題,先舉個例子說明什麼是 enhanced for loop:
|
|
在傳統的 for 迴圈中,我們使用 numbers.length
取得陣列的長度,並且宣告一個 indexer i
負責指向陣列中的第 i
個元素。
在 enhanced for loop 中,則是使用 int x: numbers
的語法,直接告訴 Java:
「請你把 numbers 中的每個元素拿出來,並用每個元素各執行一遍迴圈中的程式碼。對了!取出來的那一個元素就暫且叫它 x 吧!」
在傳統的 for 迴圈中我們是直接使用 numbers[i]
取得陣列的某個元素,所以我們也可以對陣列中的元素做修改(eg. numbers[i] = numbers[i] + 3;
:把第 i
個元素變為原值加三)
但 enhanced for loop 需要 Java 直接把整個 for loop 的每一個元素取出來,在上述例子中,我們把取出來的元素宣告為 x
。這個 x
實際上是陣列中元素的複製品,所以我們對 x 做操作並不能修改到原陣列 numbers
中的值。
a. Calculating the product of all the values in an array.
可以,計算 product 並不需要修改原陣列的值。
b. Displaying all even element values in an array.
可以,判斷是否為偶數、列印也不需要修改原陣列的值。
c. Comparing the elements in an array to a specific value.
可以,進行比較只需要取值,不需要修改原陣列。
d. Incrementing the value stored in each element of the array.
不行,增加陣列的值(比如講陣列中每個元素的值 + 5)需要修改到原陣列,不能使用 enhanced for loop。
Q14
Which statement below initializes array items to contain 3 rows and 2 columns?
a.
int[][] items = {{2, 4}, {6, 8}, {10, 12}};
b.int[][] items = {{2, 6, 10}, {4, 8, 12}};
c.int[][] items = {2, 4}, {6, 8}, {10, 12};
d.int[][] items = {2, 6, 10}, {4, 8, 12};
A14
在講 row 及 column 時建議都用英文溝通。因為中文有地區差異:有些地區
row
翻譯為行
、column
翻譯為列
;我們則是row
翻譯為列
、column
翻譯為行
。
正解:a 選項。
詳解:
首先要知道三點:
- Java 中二維
int
陣列的類型是int[][]
。 - 宣告二維陣列的時候是先看
row
再column
。 - 陣列中是以
,
分隔項。
圖解:
如圖,a 選項有 3 rows 2 columns。
從圖中可以看到,a 選項裡面用 ,
分隔的話,總共只有 3 項(圖中第二行畫斜線方塊處),其中每一項就是一個 row
。
每一個 row
裡面再以 ,
分隔,都有兩項,也就是兩個 columns
。
a.
int[][] items = {{2, 4}, {6, 8}, {10, 12}};
正解,有 3 rows 2 columns.
b.
int[][] items = {{2, 6, 10}, {4, 8, 12}};
錯誤,有 2 rows 3 columns.
c.
int[][] items = {2, 4}, {6, 8}, {10, 12};
語法錯誤,最外層只應該有一對 {}
,不能直接寫成三對 {}
。
d.
int[][] items = {2, 6, 10}, {4, 8, 12};
語法錯誤,最外層只應該有一對 {}
,不能直接寫成兩對 {}
。
Q15
Which method call converts the value in variable
stringVariable
to an integer?a.
Convert.toInt(stringVariable)
b.Convert.parseInt(stringVariable)
c.Integer.parseInt(stringVariable)
d.Integer.toInt(stringVariable)
A15
正解:c. Integer.parseInt(stringVariable)
詳解:
Convert
並非 Java 中的標準類別,要用Integer
類。Integer
類別中不存在toInt()
這個方法,要用parseInt()
方法。
你這樣到底解釋了什麼?
沒解釋什麼,這種已經定義好的用法在實務上會在需要的時候翻閱說明文檔或是上網查。作為考試的話,請你背起來。
Q16
Class
Arrays
provides method _________ for comparing arrays to determine whether they have the same contents.a. Compare
b. compares
c. equal
d. equals
A16
正解:d. equals
詳解:
假設今天有兩個 Array a
和 b
,我們想要比較兩個陣列是否**「相等」**。
當我們在做 a==b
的比較時,實際上是在比較 a
和 b
儲存的記憶體位置是否相等(也就是說:是不是指向同一個陣列)。所以 a!=b
。
如果想要知道兩個不同的陣列的元素是否全等,則該使用 equals
方法,舉例說明使用方法:
|
|
Q17
Which of the following class members should usually be private?
a. Methods.
b. Constructors.
c. Variables (or fields).
d. All of the above.
A17
這題跟 2022 年 Test1 第 2 題一模一樣,傳送門點我 。
正解:c. Variables (or fields).
一個程式中的變數 (Variables
) 或資料成員 (fields
又稱為 member variable
) 在一般情況下應該是 private
(也就是不能直接被其它 class
中成員讀取)
舉例:
|
|
通常我們不會希望其它人可以直接修改一個 Person
物件的 age
和 weight
,因為這樣可能會造成一些不可預測的後果(千年人妖)。在這個例子中,我們會在 Constructor
裡面檢查輸入的年齡有沒有在合理範圍,若超出範圍我們就認定是 18
歲(不錯吧)
a. Methods.
Methods:方法不一定要是 private
,如果像例子中的 sayMyInfo
需要給使用者調用,那就會設為 public
b. Constructors.
Constructors:Constructors 是在創造物件時會調用的方法,通常不會設為 private
。
Q18
Static class variables:
a. are final.
b. are public.
c. are private.
d. are shared by all objects of a class.
A18
這題跟 2022 年 Test1 第 8 題一模一樣,傳送門點我 。
Static 相關的說明在這篇文章的 A8 也有提及,就不重覆貼了。
Q19
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.
A19
這題跟 2022 年 Test1 第 7 題一模一樣,傳送門點我 。
正解:d. Both b and c.
不論是 b 或是 c,透過 setter 設定變數都有助於提供更完整的數據。
透過 A6 中的範例,你可以看到如果我們透過 setter 設定變數的值,就可以確保變數的值一定是我們希望的範圍。所以當 methods 提供 validity checking、instance variables 被設成 private 時,set
methods helps provide data integrity.
Q20
Instance variables declared final do not or cannot:
a. Cause syntax errors if used as a left-hand value.
b. Be initialized.
c. Be modified after they are initialized.
d. None of the above.
A20
正解:c. Be modified after they are initialized.
詳解:
final 相關的說明在這篇文章的 A8 也有提及。
a. Cause syntax errors if used as a left-hand value.
被標成 final
的變數只有在一種情況下能被賦值,那就是還沒初始化的時候:
|
|
b. Be initialized.
被標成 final
的變數當然可以被 initialized
(初始化)。你可以想想:如果一個變數是常量、又不能初始化,那它是不是沒什麼功用?
c. Be modified after they are initialized.
被標成 final
的變數是常量,被初始化後就不能改變數值了。
手寫題
接下來的部分是手寫題,需要手寫程式碼,且不能用電腦的編譯器檢查語法錯誤。
Q1(手寫)
Write a JAVA application code that generates n random numbers in the range 10-100.
[Note: Only import the Scanner and SecureRandom classes.]
A1(手寫)
要產生範圍是 10 ~ 100 的隨機數,首先要知道:
|
|
會產生 0~90 的隨機數(含 90,不含 91)
然後再把產生的數字加上 10:
|
|
即為介於 10 ~ 100 的隨機數
參考解答:
|
|
Q2-1(手寫)
What will the following program do?
|
|
A2-1(手寫)
分析一下程式碼:
- 因為
InnerClass
中的var4
是static
的變數,所以整個 InnerClass 會共用一個變數。 InnerClass2
中的var5
則不是static
的變數,所以每一個InnerClass2
型態的物件都會有自己的var5
,值不會互相影響。InnerClass
和InnerClass2
的Constructor
中都會把var4
和var5
的值加一,並且印出一行字。
所以答案為:
|
|
Q2-2(手寫)
What will the following program do?
|
|
A2-2(手寫)
分析一下程式碼:
- star 這個 method 有被重載,分為無參數、(int n)、(char ch, int n) 三個版本。
- 無參數的 star() 會呼叫 star(5)。
所以答案為:
|
|
Q2-3(手寫)
|
|
A2-3(手寫)
這題要用到 pass-by-value
和 pass-by-reference
的觀念。
當我們宣告兩個陣列 a
和 b
,並且分別將 {2, 7, 6, 3, 8, 4}
值傳給它們,它們是兩個不同的陣列,儲存著相同的值。
當我們宣告陣列 int c[] = a;
,則是把 a
陣列的記憶體位置存在 c
,也就是說,c
和 a
指向的是在記憶體中的同一個位置,我們也可以說 c
是 a
的參考。
圖解:a, b, c 陣列跟記憶體的關係。
另外看看這段程式碼:
|
|
當我們在做 a==b
的比較時,實際上是在比較 a
和 b
儲存的記憶體位置是否相等(也就是說:是不是指向同一個陣列)。所以 a!=b
。
如果想要比較的是陣列中的值有沒有相同,則需要用到本篇文章 Q16 中提到的
equals
方法。
所以此題答案為:
|
|
Q2-4(手寫)
What will the following program do?
|
|
A2-4(手寫)
如果你把程式碼丟到 IDE 裡面試著編譯執行的話,應該會跑出以下訊息:
|
|
知道錯誤在哪裡嗎?你猜猜看。
…
…
…
…
…
…
…
enum 的名稱是 Q4
,但 constructor 的名稱卻是 TrafficLight
,根本編譯不過…
那我們就回答「編譯錯誤」嗎?很抱歉,看起來是有正解。所以這裡請你假設 enum 的名稱不是 Q4
,而是 TrafficLight
…
在這題會用到一些剛剛沒看到過的 enum 用法。首先,enum 也是可以有自己的變數和方法、constructor 的:
|
|
在這裡比較好的理解方法是將 enum 宣告時列舉以外的部分(像是 constructor、或是屬性和方法)看成一般的 class 宣告。
而每一個 enum 中的枚舉則像是用這個 class 創建出的物件(像是 RED
, GREEN
, YELLOW
)。每一個 enum 的枚舉元素創建的時候都會呼叫一次 constructor,並且每一個 enum 中的枚舉元素都具有自己的屬性、方法。
示意圖:帶有 Constructor 的 enum。
由圖中可知,RED
, GREEN
, YELLOW
就像是物件一樣,都有各自的 duration
屬性和 getDuration()
方法。
因此我們把上面這段程式碼拆成兩個部分來看:
- Constructor、屬性和方法
|
|
當你把程式拆成兩個部分,並且把第 1 個部分看成是一般的 class 宣告,一切都變得很清楚:
duration
是一個private
且final
的常量TrafficLight
是 ConstructorgetDuration
是用來讓外部程式能夠取得private
變數duration
的getter
接口。
- enum 列舉元素
|
|
剛剛說到,我們可以把 enum 中枚舉的元素都當作是用 TrafficLight 這個 class 創建出來的元素,所以:
RED
是一個TrafficLight
物件,我們傳入 50 給它的 ConstructorGREEN
是一個TrafficLight
物件,我們傳入 40 給它的 ConstructorYELLOW
是一個TrafficLight
物件,我們傳入 5 給它的 Constructor
此時我們再回頭看題目中 EnumTest
的部分:
|
|
這個程式先印出 "Light\tDuration%n%n"
,其中 \t
以反斜線 \
開頭,是一個跳脫字元,代表按一下鍵盤上的 Tab
鍵。%n
則是換行。
接著看到 for(TrafficLight light : TrafficLight.values()) {}
這行:
TrafficLight.values()
會從TrafficLight
這個枚舉中取出每一個 enum 的元素(eg.RED
,GREEN
,YELLOW
)TrafficLight light
代表我們宣告light
會是以TrafficLight
這個 class 建立的物件(像RED
,GREEN
,YELLOW
都是這種物件)
所以這個 for 迴圈會把 TrafficLight
的枚舉拿出來,各進行一次迴圈:
|
|
進行迴圈時,light
會分別在第一次循環、第二次循環、第三次循環擔任 RED
, GREEN
, YELLOW
的角色。
還記得我們剛剛說,應該把 RED
, GREEN
, YELLOW
都看作是 TrafficLight
型別的物件嗎?既然它們是 TrafficLight
型別的物件,它們就會具有 getDuration()
函數可以使用。
所以看到 System.out.printf("%s\t%d%n", light, light.getDuration());
這行:
%s
代表字串,light
代表了枚舉本身,舉例,在第一次 for 循環時,%s
會印出RED
。\t
剛剛說過了,是跳脫字元,代表Tab
。%d
是十進制整數,對映到light.getDuration()
。light.getDuration()
會回傳這個枚舉的duration
屬性,舉例RED
會回傳50
。%n
剛剛說過了是換行。
所以這題的參考答案是:
|
|
答案中看起來像表格,主因是我們在輸出時都有 \t
進行對齊。
Q2-5(手寫)
What will the following program do?
|
|
A2-5(手寫)
這個程式會把 a
陣列中每個 > 30
的值加總起來。
答案 = 99+55+44+88
= 286