115 一般警察特考三等 警察資訊管理人員類別 物件導向程式設計 考古題詳解

115 年・一般警察特考・三等・警察資訊管理人員類別
試題代碼 物件導向程式設計

第 一 題30 分

請說明物件導向語言中多型(polymorphism)之前提(使用情境)和功能,並須繪製統一塑模語言(UML)之類別圖,進而舉簡潔範例程式碼說明之。

登入後即可作答並保存紀錄。

這一題的完整詳解

核心觀念

本題考查物件導向程式設計的「多型(Polymorphism)」:同一個介面、父類別參考或方法呼叫,能依實際物件型別產生不同執行結果。

多型通常建立在下列前提:

  1. 共同抽象型別 多個類別具有共同的父類別或實作相同介面。

  2. 繼承或介面實作 子類別繼承父類別的方法,或實作介面所宣告的操作。

  3. 方法覆寫(Overriding) 子類別以相同方法簽章提供自己的實作。

  4. 父類別型別的參考變數 使用父類別或介面型別的變數,指向不同子類別所建立的物件。

  5. 動態繫結(Dynamic Binding) 執行時依物件的實際型別決定要呼叫哪一個覆寫方法。

多型的核心形式可表示為:

父類別參考⟶不同子類別物件\text{父類別參考} \longrightarrow \text{不同子類別物件}

呼叫相同方法時:

相同方法名稱⟶不同執行結果\text{相同方法名稱} \longrightarrow \text{不同執行結果}

例如,Animal 是父類別,Dog 與 Cat 是子類別。雖然程式以 Animal 型別呼叫 sound,但實際物件若為 Dog,便執行狗的叫聲;實際物件若為 Cat,便執行貓的叫聲。

多型的使用情境

多型適用於下列情境:

  • 多個物件具有共同操作,但實際行為不同。
  • 程式需要處理一群不同子類別物件。
  • 希望新增子類別時,不必大幅修改既有的呼叫端程式。
  • 透過抽象化降低模組間耦合。
  • 實作可替換的元件,例如支付方式、資料庫連線、圖形物件、通知服務等。

例如,支付系統可定義共同介面 Payment,再由 CreditCardPayment、LinePayPayment、BankTransferPayment 分別實作 pay。結帳程式只需操作 Payment,不必知道實際使用哪一種支付方式。

多型的功能

1. 統一操作介面

不同類別可以透過共同的父類別或介面被一致處理。

例如:

Animal animal;
animal.sound;

呼叫端只需要知道物件具備 sound,不必依序判斷它是狗、貓或其他動物。

2. 實現行為差異化

相同的方法名稱可依不同子類別產生不同功能。

Dog.sound // 汪汪
Cat.sound // 喵喵

3. 提高可擴充性

新增 Bird 類別並覆寫 sound 後,原有的處理流程仍可使用,不需修改既有的多型呼叫架構。

4. 降低耦合

呼叫端依賴抽象型別,而非依賴具體類別,使系統更容易維護與替換。

5. 支援開放封閉原則

系統應「對擴充開放,對修改封閉」。新增子類別可擴充行為,既有程式碼不必因而大幅修改。

UML 類別圖

以下以 Animal、Dog、Cat 說明執行時多型:

 <<abstract>>
 Animal
 --------------------------------
 + sound: void
 --------------------------------
 △
 │ 繼承
 ┌────────┴────────┐
 │ │
 Dog Cat
---------------- ----------------
+ sound: void + sound: void
---------------- ----------------

若以 UML 標準表示:

  • 空心三角形箭頭指向父類別 Animal。
  • Dog 與 Cat 繼承 Animal。
  • sound 在父類別中宣告,在子類別中覆寫。
  • Animal 標示為抽象類別,代表其主要用途是提供共同規格,不直接建立一般動物物件。

範例程式碼

以下使用 Java 說明:

abstract class Animal {
 public abstract void sound;
}

class Dog extends Animal {
 @Override
 public void sound {
 System.out.println("汪汪");
 }
}

class Cat extends Animal {
 @Override
 public void sound {
 System.out.println("喵喵");
 }
}

public class Main {
 public static void main(String[] args) {
 Animal a1 = new Dog;
 Animal a2 = new Cat;

 a1.sound; // 汪汪
 a2.sound; // 喵喵
 }
}

程式執行分析

Animal a1 = new Dog;

左側的 Animal 是參考變數型別,右側建立的實際物件是 Dog。

🔒

後續完整解題步驟與【答案】

免費註冊,享 3 天全站完整詳解閱覽。

免費註冊

第 二 題30 分

請說明物件導向語言中介面(interface)之前提(使用情境)和功能,並須繪製統一塑模語言(UML)之類別圖,進而舉簡潔範例程式碼說明之。

登入後即可作答並保存紀錄。

這一題的完整詳解

核心觀念

本題考查物件導向程式設計中的「介面(Interface)」:介面的前提、使用情境、功能,以及介面與實作類別之間的 UML 關係。

介面可視為一份「共同規格」或「契約(contract)」:

  • 規定類別必須提供哪些操作方法。
  • 說明物件能做什麼,不限定物件如何完成。
  • 實作介面的類別必須完成介面所宣告的抽象方法。
  • 使用者端可依介面型別操作物件,不必依賴具體類別。
  • 同一類別可實作多個介面,因此可補足單一繼承的限制。

介面主要涉及下列物件導向概念:

  1. 抽象化:只公開必要功能,隱藏具體實作。
  2. 封裝:將功能規格集中於介面,降低使用端對實作細節的依賴。
  3. 多型:以介面型別指向不同實作類別,呼叫相同方法時產生不同結果。
  4. 低耦合:高階模組依賴介面,不直接依賴具體類別。
  5. 替換性:只要類別符合介面規格,就能在相同使用情境中相互替換。

介面的前提與使用情境

一、存在多個具有共同能力的類別

當不同類別具有相同的功能需求,但內部實作方式不同,適合抽出共同介面。

例如:

  • Payable:可付款
  • Printable:可列印
  • Serializable:可序列化
  • Loginable:可登入
  • Vehicle:可行駛

汽車、機車、卡車的行駛方式不同,但都可具備「行駛」這項共同能力,因此可由相同介面規範。

二、呼叫端只需要知道功能,不需要知道實作細節

若服務使用者只需要呼叫 pay,不需要知道付款是透過信用卡、行動支付或轉帳完成,便可設計 Payment 介面。

如此可避免呼叫端直接依賴特定實作類別。

三、需要支援多型與可替換實作

程式可將不同實作物件放入同一個介面型別的變數,呼叫相同方法:

Payment payment;

payment = new CreditCardPayment;
payment.pay;

payment = new MobilePayment;
payment.pay;

payment 雖然宣告為 Payment,實際物件可以是不同類別,這就是介面多型。

四、需要讓一個類別具備多種能力

Java 類別只能繼承一個父類別,但可以實作多個介面:

class SmartPhone implements Camera, GPS, InternetDevice {
 // 同時具備拍照、定位與上網能力
}

因此,介面適合描述「能力」或「角色」,而不是單純的父子分類。


介面的功能

一、定義共同操作規格

介面宣告方法名稱、參數與回傳型別,使各實作類別遵循相同標準。

interface Payment {
 void pay(double amount);
}

上述程式表示所有付款類別都必須提供:

pay(double amount)

二、隱藏具體實作

介面只描述「做什麼」,不描述「怎麼做」。

interface Payment {
 void pay(double amount);
}

信用卡付款與行動支付可採用不同演算法,但使用者只需要呼叫 pay。

三、提供多型

介面型別可參考不同實作類別:

Payment p1 = new CreditCardPayment;
Payment p2 = new MobilePayment;

兩個物件都可透過 Payment 型別使用,因此呼叫端不必修改主要流程。

四、降低耦合

高階程式碼依賴介面:

class OrderService {
 private Payment payment;

 public OrderService(Payment payment) {
 this.payment = payment;
 }

 public void checkout(double amount) {
 payment.pay(amount);
 }
}

OrderService 不需要知道付款方式的具體類別,只要傳入符合 Payment 介面的物件即可。

五、便於擴充與測試

新增付款方式時,只需建立新的實作類別:

class BankTransferPayment implements Payment {
 @Override
 public void pay(double amount) {
 System.out.println("銀行轉帳:" + amount);
 }
}

原有的 OrderService 不必修改,符合開放封閉原則:

  • 對擴充開放。
  • 對修改封閉。

此外,測試時可傳入假的付款物件,測試訂單流程而不必真的進行付款。


UML 類別圖

以下以付款系統為例:

 <<interface>>
 Payment
 -------------
 + pay(amount): void
 △
 │
 - - - - - - -┼- - - - - -
 │ │
 │ │
+--------------------+ +------------------+
| CreditCardPayment | | MobilePayment |
+--------------------+ +------------------+
| + pay(amount): void| | + pay(amount):void|
+--------------------+ +------------------+

+----------------------+
| OrderService |
+----------------------+
| - payment: Payment |
+----------------------+
| + checkout(amount) |
+----------------------+
 │
 │ 依賴/關聯
 └────────────── Payment

UML 符號說明

  1. <<interface>> 表示 Payment 是介面。

  2. 介面到實作類別的虛線空心三角箭頭 表示「實作(realization)」關係。

CreditCardPayment - - -▷ Payment
MobilePayment - - -▷ Payment
  1. OrderService 到 Payment 的關係 表示 OrderService 使用介面,而不是直接依賴某一個具體付款類別。

  2. + 表示 public 成員。

  3. - 表示 private 成員。


範例程式碼

以下使用 Java 說明:

🔒

後續完整解題步驟與【答案】

免費註冊,享 3 天全站完整詳解閱覽。

免費註冊

第 三 題40 分

請以物件導向語言設計一個簡易文字模式介面的登入程式。

程式需包含一般使用者(User)與高階使用者(Vuser)二個類別。一般使用者類別內之資料需包含有使用者姓名(Name)、一般密碼(Passwd)。高階使用者類別內之資料需包含有使用者姓名(Name)、安全密碼(Vpasswd)、權限等級(Vp)。

其中密碼皆十個字元,然而安全密碼必須含有英文字母大寫、英文字母小寫和數字。

作答內容除程式碼外,亦須繪製統一塑模語言(UML)之類別圖。程式語言可採用 C++、C#、Java 或 Python,程式內變數與函數的命名必須具有可讀性,另亦須撰寫完整的程式碼來驗證程式執行的正確性。

登入後即可作答並保存紀錄。

這一題的完整詳解

核心觀念

本題主要考查:

  1. 類別與物件
  • User 代表一般使用者。
  • Vuser 代表高階使用者。
  1. 繼承
  • Vuser 繼承 User,共用使用者姓名與密碼驗證功能。
  • 高階使用者再增加安全密碼及權限等級。
  1. 封裝
  • 使用私有或受保護屬性保存姓名、密碼及權限。
  • 透過方法完成登入與資料驗證,避免直接任意修改資料。
  1. 方法覆寫與多型
  • Vuser 可覆寫登入方法,加入高階使用者專屬的安全密碼驗證。
  1. 密碼格式驗證
  • 一般密碼長度必須為 10 個字元。
  • 安全密碼除長度為 10 個字元外,還必須同時包含:
  • 英文字母大寫
  • 英文字母小寫
  • 數字

UML 類別圖

 ┌──────────────────────────────┐
 │ User │
 ├──────────────────────────────┤
 │ - name: str │
 │ - password: str │
 ├──────────────────────────────┤
 │ + __init__(name, password) │
 │ + login(input_password):bool│
 │ + get_name: str │
 │ + validate_password: bool │
 └───────────────▲──────────────┘
 │ 繼承
 │
 ┌───────────────┴──────────────┐
 │ Vuser │
 ├──────────────────────────────┤
 │ - permission_level: int │
 ├──────────────────────────────┤
 │ + __init__(name, │
 │ secure_password, level) │
 │ + login(input_password):bool│
 │ + validate_secure_password│
 │ : bool │
 │ + get_permission_level:int│
 └──────────────────────────────┘

UML 關係說明

  • Vuser 與 User 為一般化/繼承關係。
  • Vuser 是 User 的特殊化類別。
  • User 負責一般使用者的姓名與一般密碼。
  • Vuser 增加權限等級,並使用更嚴格的安全密碼規則。

解題方法

本題採用 Python 實作,設計如下:

  1. 建立 User 類別:
  • 儲存使用者姓名。
  • 儲存一般密碼。
  • 建構物件時驗證密碼長度是否為 10。
  • 透過 login 方法進行登入驗證。
  1. 建立 Vuser 類別:
  • 繼承 User。
  • 增加 permission_level 權限等級。
  • 建構物件時檢查安全密碼是否同時具有大寫、小寫及數字。
  • 覆寫 login 方法,完成高階使用者登入。
  1. 建立文字模式介面:
  • 使用者輸入姓名與密碼。
  • 程式在一般使用者與高階使用者名單中尋找。
  • 驗證成功後顯示登入身分;高階使用者另顯示權限等級。
  1. 透過 run_validation_tests 進行完整測試:
  • 測試一般密碼長度。
  • 測試安全密碼規則。
  • 測試正確與錯誤密碼。
  • 測試高階使用者權限。

完整 Python 程式碼

🔒

後續完整解題步驟與【答案】

免費註冊,享 3 天全站完整詳解閱覽。

免費註冊

其他考古題

警察資訊管理人員類別《物件導向程式設計》其他年度