1 / 47

第 7 單元

第 7 單元. 7-1 物件 ( 抽象 ) 的資料型態及相關類別 (Abstract Data Types) 7-2 內部類別 (Inner Class). 7-1 物件 ( 抽象 ) 的資料型態 Object Data Types/ADT-Abstract Data Type. 抽象與封裝是設計物件的基本觀念,物件的使用者不需要知道物件內部的長相 ( 這是所謂的抽象 ) ,也不被允許直接接觸物件內部的資料 ( 這是所謂的封裝 ) 。以此觀念設計的物件稱為抽象的資料型態,簡稱 ADT 。

shana-logan
Download Presentation

第 7 單元

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. 第7單元 7-1 物件(抽象)的資料型態及相關類別(Abstract Data Types) 7-2 內部類別(Inner Class)

  2. 7-1物件(抽象)的資料型態Object Data Types/ADT-Abstract Data Type • 抽象與封裝是設計物件的基本觀念,物件的使用者不需要知道物件內部的長相(這是所謂的抽象),也不被允許直接接觸物件內部的資料(這是所謂的封裝)。以此觀念設計的物件稱為抽象的資料型態,簡稱ADT。 • 由於物件的使用者不被允許直接接觸物件內部的資料,物件乃提供了許多函數,讓使用者可以透過函數處理物件內部的資料,以保持物件資料的完整。

  3. 7-1物件(抽象)的資料型態 • 7-1-1陣列Array物件 • 陣列是資料結構的一種,它是由固定數目且資料型態相同的數值或物件Object所組成,而以一個共同的名字來存取。 • 如下列的anArray是個陣列,陣列長度是8,也就是陣列有8個元素elements,索引用來表示元素位置,anArray[0]是陣列中第一個元素,anArray[6]是陣列中第七個元素,最後一個元素是anArray[陣列長度-1]:

  4. 7-1物件(抽象)的資料型態 • 陣列的產生 • 陣列的宣告Declaration • 宣告一個變數名稱,準備存放陣列的位址 type variable-name[]; 或 type [] variable-name; 如: int month_days[]; 或 int[] month_days;

  5. 7-1物件(抽象)的資料型態 • 陣列位置的產生Allocation array-variable = new type[size]; // 中括號內指定所要配置記憶體空間的大小 如: month_days = new int[12]; 以上陣列的宣告與產生可同時進行: type variable= new type[size]; 如:int month_days = new int[12];

  6. 7-1物件(抽象)的資料型態 • 陣列的使用 • 設定陣列元素的值 如設定一月份有31天:month_days[0] = 31; 或取十二月份的天數:int days=month_days[11] ; • 設定陣列各元素的初值 • 在陣列的宣告同時可以設定陣列各元素的初值 • type variable[]={data_list}; • 如:int month_days []={31,28,31,30,31,30,31,31,30,31,30,31}; • 這種設定初值的方式不能用在宣告後的元素值設定,如 int month_days = new int[12]; month_days ={31,28,31,30,31,30,31,31,30,31,30,31}; 則不被許可

  7. 7-1物件(抽象)的資料型態 • 取得陣列的長度 • 任何時候在存取陣列元素的資料時,其索引值必須在有效的範圍內,否則會發生系統的錯誤。索引值的有效的範圍是大於等於0,小於陣列長度。所以我們在處理陣列元素時有需要知道陣列的長度如何取得: variable-name.length; • 如:int month_days = new int[12]; int months=month_days.length; // 其值為12

  8. 7-1物件(抽象)的資料型態 • 字串的陣列Arrays of String Objects • 陣列元素的資料型態不限於基本資料型態Primitive data type,也可以是物件Object的資料型態,如String就是最常用的一種。 • 如:String[] anArray4 = { "January", "February", "March",”April” };

  9. 7-1物件(抽象)的資料型態 • 陣列的複製Copying Arrays • 基本型態的資料可以用指定運算元(=號)來複製,但對於參考型態的資料必須使用特定的函數來執行: • System.arrayCopy(from, fromStart, to, toStart, count); • from: 被複製的陣列 • fromStart: 被複製陣列的起始位置 • to: 複製的陣列 • toStart: 複製陣列的起始位置 count: 複製的元素個數 • 如:System.arraycopy(copyFrom, 5, copyTo, 0, 8);

  10. 7-1物件(抽象)的資料型態 • 如果參考型態的資料用指定運算元(=號)來複製,複製的是資料的記憶體位址,而不是資料本身。如宣告另一個陣列叫 char[] copy;然後執行 copy=copyFrom; 則copy陣列變數與copyFrom陣列變數指向同一份陣列資料: • Arrays類別新增了copyOf()函數,可以直接傳回一個新的陣列物件,語法是: int[] arr2 = Arrays.copyOf(arr1, arr1.length);

  11. 7-1物件(抽象)的資料型態 • 陣列參數的傳遞 • 參考型資料如陣列、字串或其他的物件,傳遞的是實際數值所在的位址,也就是說函數所”看”到的資料和呼叫者所”看”到的資料是同一份資料,如下圖所示: • double[] adata= {1.1, 2.3, 4.2, 5.0, 6.9}; • double average_no = average(adata); • public static double average(double[] data) {// 被呼叫的函數

  12. 7-1物件(抽象)的資料型態 • 如果不想讓函數更改到”同一份資料”,就要在函數參數的變數前面加個final的保留字 public static double average(final double[] data) {

  13. 7-1物件(抽象)的資料型態 • 函數的陣列回應值Return Values • 函數產生5個小於10的亂數, 5個亂數以陣列方式回應給呼叫程式 public static int[] randomData(int length, int n) { // 被呼叫的函數Random generator = new Random(); int[] data = new int[length]; for (int i=0; i<length; i++) data[i] = generator.nextInt(n); returndata; } • 函數回應陣列給呼叫者是傳回陣列的位址

  14. 7-1物件(抽象)的資料型態 • 二維陣列 2D Arrays • 陣列的宣告 int[][] locker = new int[3][4]; • 二維陣列的實際結構先是矩陣變數指向一個一維陣列,這個一維陣列各元素再指向存放實際資料的地方。

  15. 7-1物件(抽象)的資料型態 • 二維陣列的實際結構先是矩陣變數指向一個一維陣列,這個一維陣列各元素再指向存放實際資料的地方。 雖然二維陣列是一維陣列的一種,但為了思考方便,我們將二維陣列視為一個矩陣Matrix,

  16. 7-1物件(抽象)的資料型態 • 二維陣列的初始化 locker[][]={{2,8,3,4},{9,1,2,-6},{-2,-4,5,6}}; • 二維陣列元素值的存取 locker[i][j] 指的是第i行第j列的格子,例中的locker有12個格子,各格子名稱表示如下: locker[0][0] locker[0][1] locker[0][2] locker[0][3] locker[1][0] locker[1][1] locker[1][2] locker[1][3] locker[2][0] locker[2][1] locker[2][2] locker[2][3]

  17. 7-1物件(抽象)的資料型態 • 取二維陣列的行數 • int nrows=locker.length; // = 3 • 取二維陣列的列數 • int ncols=locker[0].length; // = 4

  18. 7-1物件(抽象)的資料型態 • 陣列類別Array Class sort() // 對指定的陣列排序 binarySearch() // 對已排序的陣列進行搜尋,傳回該值所在的索引,如果沒找到就傳回負值 int[] arr = {23, 15, 13, 5, 37, 4, 12 , 7, 24, 25}; Arrays.sort(arr); int find = Arrays.binarySearch(arr, 13); 得到的find值為4

  19. 7-1物件(抽象)的資料型態 7-1-2 向量Vector 物件 • 向量(Vector)物件有與陣列同樣的功能卻沒有陣列的限制。使用陣列在宣告時必須指明陣列的元素個數,而向量物件的元素個數可以”自動成長”,無需在宣告時指明。向量可以儲存任何型態的物件,而陣列只能儲存一般數值及字串物件。 • 向量物件的使用 使用向量物件必須在程式前面引述 "import java.util.*;" 或"import java.util.Vector;" 指令。

  20. 7-1物件(抽象)的資料型態 • 向量物件的宣告 • Vector products = new Vector(); • 增加向量物件的元素 • products.add(element); • 改變向量物件的元素 • products.set(n, element);// n為元素位置,element為要置換的新元素 • 讀取向量物件的元素 • element =(objectClass)products.get(n); // objectClass為物件的資料類別 • 或element =(objectClass)products.elementAt(n); • 移除向量物件的元素 • products.remove(n);// n為元素位置

  21. 7-1物件(抽象)的資料型態 • 將數字存到向量物件 • 存入 Double d = new Double(26.89); data.add(d); • 取出 Double d=(Double)data.get(0); double x=d.doubleValue(); • 字串存到向量物件 • 存入 String s = “Danny”; data.add(s); • 取出 String s=(String)data.get(0);

  22. 7-1物件(抽象)的資料型態 • 取得向量物件的長度 • variable-name.size(); 如:int no= products.size();

  23. 7-1物件(抽象)的資料型態 7-1-3 字串String類別 • 字串String物件的產生 • 以字元陣列為參數產生字串物件 • char[] helloArray = { ‘H', 'e', 'l', 'l', 'o' }; • String Hello = new String(helloArray); • 以字串值為參數產生字串物件 • String Hello = new String(“Hello World!”;); • 直接宣告字串變數 • String Hello = “Hello World!”;

  24. 7-1物件(抽象)的資料型態 • 字串的函數 假設String data = “Hello Java! ”; (注意句尾有個空格) • 取得字串的長度 int len = data.length(); // 12 • 取得字串某個位置的字元 char aChar = data.charAt(0); // H • 取得字串中某一段字串 String data1 = data.substring(6, 10);//from [6] to [9], not include [10] String data2=data.substring(6);// from [6] to the end • 比較兩字串是否相等 boolean equ = data.eauals(“Hello Java!"); • 刪除字串頭尾的空白 String data2 = data.trim();

  25. Byte.parseByte(字串) 將字串轉為位元 Short.parseShort(字串) 將字串轉為short整數 Integer.parseInt(字串) 將字串轉為integer整數 Long.parseLong(字串) 將字串轉為long整數 Float.parseFloat(字串) 將字串轉為float浮點數 Double.parseDouble(字串) 將字串轉為double浮點數 7-1物件(抽象)的資料型態 • 字串轉為數字型態的函數

  26. char charAt(int index) 傳回指定索引處的字元 int indexOf(char ch) 傳回指定字元第一個找到的索引位置 int indexOf(String str) 傳回指定字串第一個找到的索引位置 int lastIndexOf(int ch) 傳回指定字元最後一個找到的索引位置 String substring(int beginIndex) 取出指定索引處至字串尾端的子字串 String substring(int beginIndex, int endIndex) 取出指定索引範圍子字串 char[] toCharArray() 將字串轉換為字元Array 7-1物件(抽象)的資料型態 • 與索引相關的函數

  27. 7-1物件(抽象)的資料型態 7-1-4. 字串的串接Concatenation • 字串的串接直接使用 + 運算子,+ 本來是加法運算子,而它被重新定義Override為可以直接用於字串的串接,如: String hot = “Hot”; System.out.println(“Drink “ + hot + “Java!”); 數值變數也可以+號和字串連續起來。如: System.out.println(“The total is ” + total); int a=10, b=20; System.out.print(“a+b=”+a+b); 結果顯示a+b=1020而不是我們所期望的a+b=30

  28. 7-1物件(抽象)的資料型態 7-1-5 StringBuffer類別 • String 的值不能更改, StringBuffer的值可以更改。 • StringBuffer 物件的產生 • StringBuffer buf1 = new StringBuffer("Hello Java!"); • StringBuffer buf2 = new StringBuffer( 10 ); • StringBuffer buf3 = new StringBuffer(); • StringBuffer物件的函數 • buf1.setLength(10); // 改變字串長度為10,hello Java • buf1.append(“!!”); // buf1內容變為hello Java!! • buf1.insert(0, “Hi! “); // buf1內容變為Hi! hello Java!!

  29. 7-1物件(抽象)的資料型態 7-1-6 字串的分離Split • 使用StringTokenizer類別必須引進java.util 套件 - import java.util.*; • StringTokenizer物件的產生 • StringTokenizer tokens = new StringTokenizer("I love my country"); • StringTokenizer物件的函數 int tokens.countTokens(); // 讀取Token的數目,本例為4 String tokens.nextToken(); // 讀取指標之後的Token資料, //讀完指標移至下一個 boolean tokentokens.hasMoreTokens(); // 判斷指標之後是否還有Token資料

  30. 7-1物件(抽象)的資料型態 • 使用split函數 Tokenizer函數的用法稍閒麻煩,需要用loop指令去分離字串,split是字串物件的函數,直接引用即可,而以參數指定分隔的符號(delimiter)。 stringToSplit= "I love my country"; String[] tokens = stringToSplit.split(" "); split函數執行的結果是以陣列型態回應。

  31. 7-1物件(抽象)的資料型態 7-1-7資料格式化Data Formatting • 資料格式化是將資料根據提供的樣版(pattern)加以套版,產生新的顯示樣子,方便不同場合的閱讀。 • 數字格式化- DecimalFormat double value=123456.88; String pattern="$###,###.### "; // 設定格式化樣版 DecimalFormat myFormatter = new DecimalFormat(pattern); // 以指定的樣版pattern實作格式化物件myFormatter String output = myFormatter.format(value); // 引用格式化物件的format函數 System.out.println(output); // 將格式化後的字串顯示出來

  32. 7-1物件(抽象)的資料型態 • 日期、時間的格式化- DateFormat的使用: Date now = new Date(); // 取得當天的日期物件 System.out.println(now.toString()); 顯示樣式Sun Mar 04 20:14:11 PDT 2007 如果要顯示其他的樣式,要使用DateFormat 物件中的三種函數: DateFormat.getInstance().format(日期物件) // 顯示最簡短的日期時間 DateFormat.getTimeInstance().format(日期物件) // 格式化時間 DateFormat.getDateTimeInstance().format(日期物件) // 格式化日期時間

  33. 7-1物件(抽象)的資料型態 • 文字訊息格式化- MessageFormat的使用: • 文字訊息格式化容許許多日期、時間以及文字片段插入一段文句中間的任何位置。 At 12:30 PM on Jul 3, 2053, there was a disturbance in the Force on planet 7. 寫法是先將每個變動資料以物件型態置於一個物件陣列中。然後引用MessageFormat類別的format函數MessageFormat.format(String, Object);產生字串結果。 函數的第一個參數是固定文句和插入點的插入索引與樣版(如下面的句子陰影部份),索引是變動資料在物件陣列中的位址。

  34. 7-1物件(抽象)的資料型態 At 12:30 PM on Jul 3, 2053, there was a disturbance in the Force on planet 7. Object[] arguments = { new Integer(7), // 索引值為0 new Date(System.currentTimeMillis()), // 索引值為1 "a disturbance in the Force" // 索引值為2 }; String result = MessageFormat.format( "At {1,time} on {1,date}, there was {2} on planet {0,number,integer}.", arguments); System.out.print(result);

  35. 7-1物件(抽象)的資料型態 7-1-8 定型表示式 Regular expression • 上節說明資料顯示時可以有一定的式樣,反過來輸入的資料也可以規定必須有一定的式樣,如輸入電話號碼必須是02-29172345式樣,這種輸入資料式樣的規定就叫定型表示式。 • 定型表示式可以用下表的定型碼來規定字串字元的式樣,準備好定型表示式後引用Pattern類別的matches()函數來比對所要檢查的字串。

  36. 7-1物件(抽象)的資料型態 • 如檢查字串首三字必須是非數字,後三字必須是數字: String REGEXP = “\\D\\D\\D\\d\\d\\d”; // 定義定型表示式 if (INPUT1.matches(REGEXP)) // 比對字串是否符合定型表示式規定 System.out.println(“INPUT1 Match”); • 如果同一定型碼出現許多,可以下表所列方式定義定型表示式:(X表示定型碼)

  37. 7-1物件(抽象)的資料型態 String REGEXP = “\\D\\D\\D\\d\\d\\d”; 可改寫為 REGEXP = “\\D{3}\\d{3}” 或REGEXP = “[^0-9]{3}[0-9]{3}” 如檢查身分證號碼A123456789格式是否正確的定型表示式為\\w\\d{9}。w是第一個字元必須是字母,d{9}表示要有九位數字。 • 也可以使用字元類別做一組一組的比對,如:

  38. 7-1物件(抽象)的資料型態 例如檢查電子郵件格式是否正確? 電子郵件定型表示式為 [a-z0-9._%-]+@[a-z0-9.-]+([.][a-z]{2,4}) String REGEXP ="[a-z0-9._%-]+@[a-z0-9.-]+([.][a-z]{2,4})"; if(INPUT1.matches(REGEXP)) System.out.println("INPUT1 format correct"); else System.out.println("INPUT1 format error");

  39. 7-1物件(抽象)的資料型態 • 其他的函數: replaceAll()函數 將字串abcdebcaddbc內的bc改為大寫BC String INPUT = "abcdebcaddbc"; System.out.print(INPUT.replaceAll(REGEXP, "BC")); replaceFirst()函數 將字串abcdebcaddbc內的第一個bc改為大寫BC String INPUT = "abcdebcaddbc"; System.out.print(INPUT.replaceFirst(REGEXP, "BC")); split()函數 將字串the darwinian devonian explodian chicken以ian為分割點加以分段: String REGEXP ="ian"; String INPUT="the darwinian devonian explodian chicken"; Pattern p = Pattern.compile(REGEXP); String[] x = p.split(INPUT);

  40. 7-1物件(抽象)的資料型態 7-1-9 數字類別NumbersClasses • 數字類別有許多的子類別: • 整數的子類別: 建構函數: Integer intObj=new Integer(100); // 以整數型式宣告整數物件 Integer intObj=new Integer(“100”); // 以字串型式宣告整數物件 Integer intObj = 100;

  41. 7-1物件(抽象)的資料型態 成員函數: intObj.intValue(); // 將整數物件轉成整數數值 intObj.doubleValue(); // 將整數物件轉成小數數值 intObj.toString(); // 將整數物件轉成字串 intObj.byteValue(); // 整數物件轉成字元 intObj1.compareTo(intObj2); // 比較兩個整數物件,小於時回-1、等於時回0、大於時回1 intObj1.equals(intObj2); // 比較兩個整數物件是否相等,並回應true 或false的邏輯值 整數與字串的轉換 int i = Integer.parseInt(s.trim()); // 將字串轉成整數 String s = Integer.toString(int i); //將整數轉成字串

  42. 7-1物件(抽象)的資料型態 7-1-10 數學函數 • java.lang.Math中常用的數學函數有: (type of a) Math.abs(a); // 取a的絕對值 (type of a) Math.max(a,b); // 取a, b最大值 (type of a) Math.min(a,b); // 取a, b最小值 double Math.pow(double a, double b); // 取a的b次方值(即ab) float Math.random(); // 傳回大於等於0.0,小於1.0的隨機亂數 int Math.round(float a); // 取a的整數值 double Math.sqrt(double a); // 取a的平方根值(a>=0) double Math.sin(double a); // 取a的sin三角函數值(a以弳度radian為單位)

  43. 7-1物件(抽象)的資料型態 7-1-11 亂數類別Random Class • 亂數值的產生除了引用數學函數外,還可使用亂數類別: Random generator = new Random(); nextInt(n); //傳回大於等於0,小於n的隨機亂數(整數) nextDouble(); // 傳回大於等於0.0,小於1.0的隨機亂數(小數) • 如:產生擲骰子1到6的隨機亂數 Dice_no = 1 + generator.nextInt(6); 或 Dice_no = (int)Math.random()*6 + 1; // 使用數學函數

  44. 7-2 內部類別Inner Class 7-2-1何謂內部類別? • 類別中還可以再定義類別,稱之為內部類別Inner class或巢狀類別Nested class。 • 內部類別可以是繼承某個類別或是實作某個介面或是獨立的類別,它可以直接存取外部類別的變數與函數(包括私用private的),而不必透過參數的傳遞。 • 內部類別可以分為三種: • 成員內部類別(Member inner class) • 區域內部類別(Local inner class) • 匿名內部類別(Anonymous inner class)

  45. 7-2 內部類別Inner Class • 成員內部類別(Member inner class) 成員內部類別是直接在外部類別內宣告類別為成員,如同宣告成員變數與成員函數一樣。 public class OuterClass { : public void MyMethod() { }private class InnerClass { // 成員內部類別:} InnerClass inner=new InnerClass(); }

  46. 7-2 內部類別Inner Class • 區域內部類別(Local inner class) 區域內部類別是定義於外部類別的函數中,類別的物件生成僅止於該函數中有效 。 public class OuterClass { : public void MyMethod() { class InnerClass { // 區域內部類別 : } InnerClass inner=new InnerClass(); } }

  47. 7-2 內部類別Inner Class • 匿名內部類別(Anonymous inner class) 匿名內部類別是沒有宣告名稱的內部類別,使用時直接以new產生物件。 public class OuterClass extends Applet { : public void MyMethod() { new ActionListener { // 匿名內部類別 : } } }

More Related