1 / 43

陣列與多型

陣列. 陣列與多型. 借用上一章中, Worker 、 HourlyWorker 以及 SalaryWorker 的範例來說明多型應用於陣列的情形。 公司內有些員工是 SalaryWorker ,有些是 HourlyWorker 。. Worker[] w = new Worker[5];. if(choice.equals("h")) { number = JOptionPane.showInputDialog(" 輸入工作時數 "); w[i] = new HourlyWorker(name, Integer.parseInt(number));

walter
Download Presentation

陣列與多型

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 陣列

  2. 陣列與多型 借用上一章中,Worker、HourlyWorker 以及 SalaryWorker的範例來說明多型應用於陣列的情形。 公司內有些員工是 SalaryWorker,有些是 HourlyWorker。 Worker[] w = new Worker[5]; if(choice.equals("h")) { number = JOptionPane.showInputDialog("輸入工作時數"); w[i] = new HourlyWorker(name, Integer.parseInt(number)); } else { number = JOptionPane.showInputDialog("輸入年薪"); w[i] = new SalaryWorker(name, Integer.parseInt(number)); }

  3. 練習題 • 請修改上述人事系統,使得該系統也能分別產生 HourlyWorker 和 SalaryWorker 的總薪資。 • (Optional)為了提高重複使用性,請設計一個 Personnel 類別,該類別物件包含全公司的員工薪資資料,除了計算總薪資之外,使用者還可以經由 add()、delete()、update()、query() 來新增、刪除、修改、查詢員工薪資。

  4. 練習題 • 繼續之前 Circle/Rectangle 的範例, • 請設計一套系統,使得使用者可以產生[任意/固定]個 Circle 或者 Rectangle 物件,也允許使用者在任意時間指定某特定物件的周邊長/面積,或者目前各種物件的個數、總周邊長、總面積等資訊。 • 顯示物件資訊的格式: • Circle 總數為 2 • 半徑為 4.2 • 半徑為 3.1 • Rectangle 總數 1 • 長為 1.2、寬為 4.5

  5. 陣列與 main 方法 在控制類別內的 main 方法 public static void main(String[] args) { javac Test.java dir /w *.java args.length為4 java Test 1 22 3 14

  6. 執行結果

  7. 範例 • java Test1 this is a book • java Test1 “this is” “a book” • args.length 為 2,args[0] 為 this is,而 args[1]為 a book

  8. 練習題 • 請完成 Test1。 • 請寫一個控制類別,使得如果使用者輸入java TestWorker h John 44,則程式會產生一個 HourlyWorker 的物件,並列印出John 的薪資;同樣的,如果使用者輸入java TestWorker s Mary 420000,則程式會產生一個 SalaryWorker 的物件,並列印出 Mary 的薪資。

  9. 練習題 • JOptionPane.showOptionDialog( ) 允許你做出一個可供選擇的對話視窗,而允許使用者選取的字串放在一個陣列中。請參考 JOptionPane.showOptionDialog( ) 的文件,並修改之前的 TestWorker,使得使用者只用選擇 HourlyWorker 或者 SalaryWorker。

  10. 練習題 • 假設公司內有三個部門,分別是人事室、行銷課、以及製造課。每一個課裡面都只有 5 個員工,每一個員工不是 HourlyWorker、就是 SalaryWorker。請利用隨機的方式決定員工是 HourlyWorker、還是 SalaryWorker,也利用隨機的方式產生薪資或者工作時數,至於員工姓名就以代號從 1 編到 15。最後,請計算並列印出每一個員工的清單、該部門的總薪資、以及該公司的總薪資。 • (Optional) 請設計一個 Personnel 的類別來代表前一題中的陣列。

  11. 陣列的限制 • 陣列很好用,可是一旦它的大小確定了之後,它的大小就不能改變。 • Worker[] w = new Worker[5]; • 當 w 不足以存放公司的員工時,我們必須 • Worker nw = new Worker[10]; • 將 w 的內容一個個複製到 nw。 • 可以 w = nw; 嗎? • 陣列可以輕易的新增、刪除、修改、查詢嗎?

  12. ArrayList • ArrayList 和 TreeMap 是 Java 提供的類別,它們的目的跟陣列相同,都是為了能夠有效處理一堆物件的一種資料結構 • 這兩個類別都是屬於 java.util 這個套件內 • 這些用來處理一堆物件的類別統稱為 JCF (Java Collection Framework)

  13. ArrayList 特色 • 因為一個 ArrayList 沒有所謂的大小限制,程式設計師也不必事先決定一個 ArrayList 的大小 • 我們可以隨時加進一個物件,而不必擔心加入一個物件之後會不會超出陣列原先設定的大小,想加就加 • 想要把 ArrayList 中的元素移除,直接使用remove() 的方法直接移除 • 想要取得 ArrayList 中的某個特定位置的物件,也可以像陣列一樣,指定索引值就可以

  14. ArrayList • List 的觀念其實很像陣列,以數學的表達方式就像 • L=(l0, l1, l2,…, lN) • L 代表一個 List,而每一個 List 裡面包含許多元素 • 以我們常見的座標(x, y)和(x, y, z)為例,l0 就是 x,l1 就是 y,而 l2 就是 z

  15. 常用的方法 • boolean add(E e):這個方法會把傳進來的物件 e 加到 list 的最後面; • 如果加入的動作完成,則回傳 true。至於 e 的資料型態為 E,這代表泛型,我們暫時把它當成一個類別型態 • void add(int index, E e):如果需要把傳進來的物件 e 加到 list 的某個特定位置 index,則使用這個 add() 方法 • void clear():這個方法會把 list 內的所有元素刪除 • E get(int index):這個方法會取得 list 內位於 index 位置的物件 • E remove(int index):這個方法會把 list 內的位於 index 的元素刪除,並將刪除的元素回傳 • E set(int index, E e):這個方法會把傳入的 e 用來取代原先在 index 位置的舊元素,並且把舊元素回傳 • int size():回傳 list 目前所擁有的元素數量

  16. 執行結果

  17. 程式改寫 • 第30-31行,其實這兩行可以改成 • System.out.println( ( (Worker) p.get(i) ).toString()); • TestList.java uses unchecked or unsafe operations. • 必須使用泛型來消除

  18. 練習題 • 請把 TestList 的第 17-19 行,改寫成一行,而不需要另外宣告一個 Worker 物件w。

  19. 泛型(Generic Type) • 讓我們以 add() 和 get() 這兩個方法來說明。在 JDK 1.5 版之前,這兩個方法的定義如下: • void add(Object o):這個方法是用來將物件 o加入 ArrayList • Object get(int index):這個方法是取得位於index 的物件,該物件的資料型態為 Object • 由於 Object 是所有類別的祖先類別,且由於繼承的特色(或者嚴格的說,向上轉型的特色),我們可以在 ArrayList 中加入任意物件,例如我們可以加入Worker、HourlyWorker、Product、Book、String、Date 等

  20. 執行結果 將程式的第 30 行 Worker w = (Worker) p.get(i);改成 Worker w = p.get(i);

  21. 泛型 • 畫面中顯示: • p.get(i) 回傳的是 Object,當然無法 downcast,一定需要強迫轉型。 • 所謂的 ”unsafe operation” 跟 type safety有關:所謂 type safety 的問題,說的是如果一個程式語言的設計可以避免發生資料型態轉換的錯誤,那麼這個程式語言就是 type safe。

  22. 範例 ArrayList any = new ArrayList(); any.add(“Hello”); any.add(new Worker(“John”, 34000)); any.add(new Date()); any 是一個 ArrayList 的物件,其第一個位置的物件是一個字串,第二個位置的物件是一個 Worker 物件,而第三個位置的物件是一個 Date 物件

  23. 範例 如果位置忘了,而不小心寫成 Worker w = (Worker) any.get(2); 編譯沒問題,在執行時卻出了狀況,這代表一個 unsafe 的狀況。好的設計,應該在編譯的時候就指出問題。

  24. 泛型宣告 • 泛型宣告的方式就是在 ArrayList(或者其他 JCF 的類別)之後加上一對 <、> 括號 • 在 <> 之中加入所需要的類別 • 假設我們希望產生的 any 是一個 ArrayList 物件,而且其元素都屬於 String 型態,那麼我們就可以把 any 宣告成 • ArrayList<String> any = new ArrayList<String>();

  25. 範例 import java.util.*; public class TestList3 { public static void main(String[] args) { ArrayList<String> any = new ArrayList<String>(); any.add("Hello"); any.add(new Worker("John", 34000)); any.add(new Date()); Worker w = (Worker) any.get(2); } }

  26. 執行結果

  27. 泛型 • 由於 Java 支援泛型,Java 是一個 type safe 的程式語言。 • 這個特色是在 JDK 1.5 版之後才有的

  28. 練習題 • 在之前的範例中,我們宣告了 Circle/Rectangle 的陣列,這次請改成利用 ArrayList 來代表並使用泛型,請做必要的修改。

  29. TreeMap • Map 的資料結構基本上是像是一個有兩個欄位的表格 • 第一個欄位叫做 key,第二個欄位代表資料 • 在 Map 中的每一筆資料都是由(key, 資料)所表示 • 這樣成雙成對的結構叫做 entry,或叫作 map entry

  30. TreeMap

  31. TreeMap • 在 ArrayList 裡面找資料,程式需要從第一筆一直找到最後一筆,或者一直找到為止 • 而 Map 的作用就在於,只要程式設計人員指定一個資料的 key 值(可以把它想成資料的名稱),Map 就會把對應於該 key 值的資料傳回來

  32. 常用的幾個方法 • V put(K key, V value):把傳進來的物件 value 加到 map的 key 的位置上; • 如果之前在 key 所在的位置上沒有資料,put() 回傳 null;反之,如果之前在 key 所在的位置上已經有資料了,則 value 會取代原來的資料,而且 put() 回傳原來的資料 • void clear():將 map 內的所有 entry 刪除。 • V get(Object key):取得 map 內對應於 key 值的資料 • V remove(Object key):依據 key 找出 map 內的 entry 予以刪除,並將刪除的資料回傳。 • 如果 remove() 找不到對應的 key,則回傳 null • int size():回傳 map 內目前所擁有的 entry 數量

  33. TreeMap • TreeMap 實作 Map,因此 TreeMap 也提供了這幾個方法給程式設計人員使用 • 在下列的範例中,我們利用 TreeMap 的資料結構來取代之前的 Worker 陣列personnel

  34. 06 TreeMap<String,Worker> personnel = new TreeMap<String,Worker>(); 11 personnel.put("M001", new Worker("John", 32000)); 12 personnel.put("A003", new Worker("Mary", 34000)); 13 personnel.put("M010", new Worker("Dave", 25000)); 16 Worker w = (Worker) personnel.get("A003"); 17 w.setName("Eric"); 18 personnel.put("A003", w); 19 personnel.remove("M001"); 22 w = (Worker) personnel.get("M001"); 23 if(w != null) 24 System.out.println(w.toString()); 26 w = (Worker) personnel.get("A003"); 27 if(w != null) 28 System.out.println(w.toString()); 30 w = (Worker) personnel.get("M010"); 31 if(w != null) 32 System.out.println(w.toString());

  35. 執行結果

  36. 練習題 • 請修改 TestMap 的第 22-32 行,使得修改後,只有下列三行,並新增所需要的display()方法: display(“M001”, personnel); display(“A003”, personnel); display(“M010”, personnel); • 請問,如果事先並不知道一個 TreeMap 中的 (key, value) pairs 有哪些,請問有什麼辦法可以把所有的 (key, value) pairs 列印出來?(提示:查看 APIs)

  37. 傳遞”任意個”引數給方法 • 傳統上,當定義方法的時候,我們已經決定了該方法的參數個數;可是,有時候我們去需要定義一個方法,使得呼叫端方法可以傳遞”任意個”引數給該方法! • 例如:我們常用的 String.format(String format, Object… args)。仔細想想,我們可以在 “format” 之後,加上任意個參數。

  38. 傳遞”任意個”引數給方法 • Java 支援這種定義方式,而這樣的結構稱為 “varargs”。 • 使用 varargs 來定義方法,其方式是在參數資料型態的後面立即(不能有空格)加上三個點 • public void display(String… msg) • msg 的處理方式跟陣列相同 • 呼叫端可以傳遞任意個引數(也可以沒有) • display() • display(“Hello”); • display(“Hello”, “World”); • display(字串陣列); • 資料型態可以是基本資料型態,也可以是類別。

  39. 範例 private static void display(String... msg) { System.out.println(msg.length); for(int i=0; i<msg.length; i++) System.out.println(msg[i]); System.out.println(); } private static void display(int... num) { System.out.println(num.length); for(int i=0; i<num.length; i++) System.out.println(num[i]); System.out.println(); } } public class TestMM { public static void main(String[] args) { display("Hello"); display("Hello", "World"); display("Hello", "World", "Again"); display(1); display(1,2); display(1,2,3); }

More Related