201871010123-吳麗麗《面向對象程序設計(Java)》第八週學習總結html
項目 | 內容 |
這個做業屬於哪一個課程 | http://www.cnblogs.com/nwnu-daizh/ |
這個做業要求在哪裏 | https://www.cnblogs.com/nwnu-daizh/p/11703678.html |
做業的學習目標 |
|
第一部分:理論部分java
第六章 接口、lambda表達式與內部類express
6.1.1接口編程
1) Java爲了克服單繼承的缺點,Java使用了接口,一個類能夠實現一個或多個接口。設計模式
2) 在Java程序設計語言中,接口不是類,而是對類的一組需求描述,由常量和一組抽象方法組成。數組
3) 接口中不包括變量和有具體實現的方法。函數
4) 只要類實現了接口,則該類要聽從接口描述的統一格式進行定義,而且能夠在任何須要該接口的地方使用這個類的對象.工具
5)聲明方式: public interface 接口名 { …… } 接口體中包含常量定義和方法定義,接口中只進行方法的聲明,不提供方法的實現。學習
6)相似創建類的繼承關係,接口也能夠擴展。 接口的擴展技術使得從具備較高通用性的接口存在多條鏈延伸到具備較高專用性的接口。測試
擴展方法: public interface 接口1 extends 接口2 { …… }
說明:
a)一般接口的名字以able或ible結尾;
b)可使用extends來繼承接口的常量和抽象方法,擴展造成新的接口;
c)接口中的全部常量必須是public static final,方法必須是public abstract,這是系統默認的,無論你在定義接口時,寫不寫修飾符都是同樣的
7)在類聲明時用implements關鍵字聲明使用一個或多個接口
class Employee implements Printable { …… }
一個類使用了某個接口,那麼這個類必須實現該接口的全部方法,即爲這些方法提供方法體。
一個類能夠實現多個接口,接口間應該用逗號分隔開。
class Employee implements Cloneable,Comparable
說明:
a)若實現接口的類不是抽象類,則必須實現全部接口的全部方法,即爲全部抽象方法定義方法體
b)一個類在實現某接口抽象方法時,必須使用徹底相同的方法名、參數列表和返回值類型
c)接口抽象方法的訪問控制符已指定爲public,因此在類的實現時,必須顯示地使用public修飾符,不然被警告縮小了接口中定義的方法的訪問控制範圍。
8)接口不能構造接口對象,但能夠聲明接口變量以指向一個實現了該接口的類對象。
Comparablex = new Comparable(…); //ERROR
Comparable x= new Employee(…); //OK
9) 能夠用instanceof檢查對象是否實現了某個接口。
if (anObject instanceof Comparable) { ……}
6.1.2 接口與抽象類
1)抽象類:用abstract來聲明,沒有具體實例對象的類,不能用new來建立對象。可包含常規類所包含的任何東西。
抽象類必須由子類繼承,若是abstract類的子類不是抽象類,那麼子類必須重寫父類中全部的abstract方法。
2)接口:用interfaces聲明,是抽象方法和常量值定義的集合。從本質上講,接口是一個特殊的抽象類,這種抽象類中只包含
常量和方法的定義,而沒有變量和方法的定義。接口中只能定義抽象方法,並且這些方法默認爲public的。只有類實
現了接口,就能夠在任何須要該接口的地方使用這個類的對象。此外,一個類能夠實現多個接口。
接口與抽象類的區別:
(1)接口不能實現任何方法,而抽象類能夠。
(2)類能夠實現許多接口,但只有一個父類。
(3)接口不是類分級結構的一部分,無任何聯繫的類能夠實現相同的接口。
6.2.1 接口實例
1)回調(callback):一種程序設計模式,在這種模式中,可指出某個特定事件發生時程序應該採起的動做。 在java.swing包中有一個Timer類,
可使用它在到達給定的時間間隔時觸發一個事件。
-Timer(intinterval, ActionListenerlistener)
- void start()
-void stop()
2)Comparator接口
a)所在包:java.util.*
b)Comparator接口定義
public interface Comparator<T>{
int compare(T o1,T o2);
......
}
c)用途一:處理字符串按長度進行排序操做
3) Object類的Clone方法
a)當拷貝一個對象變量時,原始變量與拷貝變量引用同一個對象。這樣,改變一個變量所引用的對象會對另外一個變量產生影響。
b)若是要建立一個對象新的copy,它的最初狀態與 original同樣,但之後能夠各自改變狀態,就須要使用Object類的clone方法。
c)Object類的clone()方法是一個native方法。
d)Object類中的clone()方法被protected()修飾符修飾。這意味着在用戶編寫的代碼中不能直接調用它。若是要直接應用clone()方法,
就需覆蓋clone()方法,並要把clone()方法的屬性設置爲public。
e)Object.clone()方法返回一個Object對象。必須進行強制類型轉換才能獲得所須要的類型。
4)淺層拷貝:被拷貝對象的全部常量成員和基本類型屬性都有與原來對象相同的拷貝值,而若成員域是一個對象,則被拷貝對象該對象域的對象引用仍然指向原來的對象。
5)深層拷貝:被拷貝對象的全部成員域都含有與原 來對象相同的值,且對象域將指向被複制過的新對 象,而不是原有對象被引用的對象。換言之,深層拷貝將拷貝對象內引用的對象也拷貝一遍。
6.2.2 Java中對象克隆的實現
1)在子類中實現Cloneable接口
2)爲了得到對象的一份拷貝,能夠利用Object類的clone方法。
3)在子類中覆蓋超類的clone方法,聲明爲public。
4)在子類的clone方法中,調用super.clone()。
6.3 Lambda表達式
1)Java Lambda表達式是Java 8引入的一個新的功能,主要用途是提供一個函數化的語法來簡化編碼。
2)Lambda表達式本質上是一個匿名方法。
public intadd(intx, inty) {
return x + y; }
轉成Lambda表達式後是:
(intx, inty) -> x + y;
參數類型也能夠省略,java編譯器會根據上下文推斷出來
3)Lambda表達式的語法基本結構
(arguments)->body
有以下幾種狀況:
a)參數類型可推導時,不須要指定類型,如
(a)->System.out.println(a)
b)只有一個參數且類型可推導時,不強制寫(),如
a->System.out.println(a)
c)參數指定類型時,必須有括號,如(int a)->System.out.println(a)
d)參數能夠爲空,如()->System.out.println("hello")
e)body須要用{}包含語句,當只有一條語句時{}可省略
4)函數式接口Functionallnterface
a)Java Lambda表達式以函數式接口爲應用基礎
b)函數式接口(Functionallnterface)
只有一個方法的接口,這類接口的目的是爲了一個單一的操做。常見的接口如:ActionListener,Runnable,Comparator都是函數式接口,而且都
標註了註解@Functionallnterface.
c)函數式接口用做表示lambda表達式的類型。
6.4.1 內部類
1)內部類(inner class)是定義在一個類內部的類。
2)外層的類成爲外部類(outer class).
3)內部類主要用於事件處理。 使用內部類的緣由有如下三個:
a)內部類方法能夠訪問該類定義所在的做用域中的數據,包括私有數據。
b)內部類可以隱藏起來,不爲同一包中的其餘類所見。
c)想要定義一個回調函數且不想編寫大量代碼時, 使用匿名內部類比較便捷。
4)內部類的聲明
內部類的聲明格式以下:
[修飾符] class outerClass{
...
[修飾符]class innerClass{
...
}
...
}
5)內部類能夠直接訪問外部類的成員,包括private成員,可是內部類的成員卻不能被外部類直接訪問。內部類中加上修飾符訪問外部類中的同名域。
6.4.2局部內部類
1)內部類並不是只能在類內定義,也能夠在程序塊內定義局部內部類。例如,在方法中,甚至在for循環體內部。
2)局部內部類不能用public或private訪問修飾符進行聲明,它的做用域被限定在聲明這個局部類的塊中。
3)局部內部類能夠訪問方法中的final類型的局部變量。
6.4.3 匿名內部類
1)若只建立類的一個對象,則不應爲該類命名,這種類稱爲匿名內部類。
2)因爲匿名類沒有類名,因此匿名類不能有構造器,取而代之的是將構造器參數傳遞給超類的構造器。
3)若匿名內部類實現接口時,則匿名內部類不能有任何構造參數。
4)若是構造參數的閉圓括號跟一個開花括號,代表正在定義的就是匿名內部類。
6.4.4 靜態內部類
1)若是用static修飾一個內部類,這個類就至關因而一個外部定義的類,因此static的內部類中能夠聲明static成員,但非static的內部類中的成員不能聲明爲static的。
static的內部類不能再使用外部類的非static的成員變量。
2)static內部類不多使用。
第二部分:實驗部分——接口的定義與使用
1、實驗目的與要求
(1) 掌握接口定義方法;
(2)掌握實現接口類的定義要求;
(3)掌握實現了接口類的使用要求;
(4)掌握程序回調設計程序;
(5) 掌握Comparator接口用法;
(6) 掌握對象淺層拷貝與深層拷貝方法;
(7) 掌握Lambda表達式語法;
(8) 瞭解內部類的用途及語法要求。
2、實驗內容和步驟
實驗1: 導入第6章示例程序,測試程序並進行代碼註釋。
測試程序1:
a)編輯、編譯、調試運行閱讀教材214頁-215頁程序6-1、6-2,理解程序並分析程序運行結果;
b) 在程序中相關代碼處添加新知識的註釋。
c)掌握接口的實現用法;
d)掌握內置接口Compareable的用法。
EmployeeSortTest代碼以下:
package interfaces; import java.util.*; /** * This program demonstrates the use of the Comparable interface. * @version 1.30 2004-02-27 * @author Cay Horstmann */ public class EmployeeSortTest { public static void main(String[] args) { var staff = new Employee[3]; staff[0] = new Employee("Harry Hacker", 35000); staff[1] = new Employee("Carl Cracker", 75000); staff[2] = new Employee("Tony Tester", 38000); Arrays.sort(staff); //使用Arrays中的sort方法對Employee對象數組進行排序 // print out information about all Employee objects for (Employee e : staff) System.out.println("name=" + e.getName() + ",salary=" + e.getSalary()); } }
Employee類代碼以下:
package interfaces; public class Employee implements Comparable<Employee> // Employee類實現Comparable接口 { private String name; private double salary; public Employee(String name, double salary) { this.name = name; this.salary = salary; } public String getName() { return name; } public double getSalary() { return salary; } public void raiseSalary(double byPercent) { double raise = salary * byPercent / 100; salary += raise; } /** * Compares employees by salary * * @param other another Employee object * @return a negative value if this employee has a lower salary than * otherObject, 0 if the salaries are the same, a positive value * otherwise */ public int compareTo(Employee other) //重寫接口的compareTo方法 { return Double.compare(salary, other.salary);//按照他們的工資高低進行排序 } }
程序運行結果以下:
實現小結:
1)任何實現Comparable接口的類都須要包含compareTo方法,而且這個方法的參數必須是一個Object對象,返回一個整型數值。
2)爲了讓類實現一個接口,一般須要如下兩個步驟:
a)將類聲明爲實現給定的接口
b)對接口中的全部方法進行定義
測試程序2:
編輯、編譯、調試如下程序,結合程序運行結果理解程序;
代碼以下:
1 interface A 2 { 3 double g=9.8; 4 void show( ); 5 } 6 class C implements A 7 { 8 public void show( ) 9 {System.out.println("g="+g);} 10 } 11 12 class InterfaceTest 13 { 14 public static void main(String[ ] args) 15 { 16 A a=new C( ); 17 a.show( ); 18 System.out.println("g="+C.g); 19 } 20 }
程序運行結果以下:
測試程序3:
a)在elipse IDE中調試運行教材223頁6-3,結合程序運行結果理解程序;
b)26行、36行代碼參閱224頁,詳細內容涉及教材12章。
c)在程序中相關代碼處添加新知識的註釋。
d)掌握回調程序設計模式;
程序代碼以下:
package timer; /** @version 1.02 2017-12-14 @author Cay Horstmann */ import java.awt.*; import java.awt.event.*; import java.time.*; import javax.swing.*; public class TimerTest { public static void main(String[] args) { var listener = new TimePrinter(); //構建一個新的對象 // construct a timer that calls the listener // once every second var timer = new Timer(1000, listener); //構建類的一個對象,並將它傳遞給Timer構造器 timer.start(); //調用timer的start方法 // keep program running until the user selects "OK" 保持一個對話框直到使用者選擇OK JOptionPane.showMessageDialog(null, "Quit program?"); System.exit(0); } } class TimePrinter implements ActionListener //TimePrinter類實現ActionListener接口 { public void actionPerformed(ActionEvent event) //重寫接口的方法 { System.out.println("At the tone, the time is " + Instant.ofEpochMilli(event.getWhen())); Toolkit.getDefaultToolkit().beep(); //得到默認的工具箱 } }
程序運行結果以下:
按肯定後其程序才結束
實驗小結:
1)回調(callback)是一種常見的程序設計模式。在這種模式中,能夠指定某個特定事件發生時應該採起的動做。
2)在該實驗中該程序構造定時器,其設置了一個時間間隔,並告知定時器,當到達時間間隔時須要作什麼操做。
3)如何告知定時器作什麼?在不少程序設計語言中,能夠提供一個函數名,定時器週期性地調用它。可是,在java標準庫中的類採用面向對象方法,它將某個類的對象傳遞給定時器,而後定時器調用這個對象的方法。傳遞一個對象比傳遞一個函數要靈活的多。
4)Timer構造器的第一個參數是發出通告的時間間隔,它的單位是毫秒。第二個參數是監聽器對象。
測試程序4:
a)調試運行教材229頁-231頁程序6-4、6-5,結合程序運行結果理解程序;
b)在程序中相關代碼處添加新知識的註釋。
c)掌握對象克隆實現技術;
d)掌握淺拷貝和深拷貝的差異。
CloneTest代碼以下:
package clone; /** * This program demonstrates cloning. * @version 1.11 2018-03-16 * @author Cay Horstmann */ public class CloneTest { public static void main(String[] args) throws CloneNotSupportedException { var original = new Employee("John Q. Public", 50000); //建立一個對象並進行初始化 original.setHireDay(2000, 1, 1); Employee copy = original.clone(); //對象克隆 copy.raiseSalary(10); copy.setHireDay(2002, 12, 31); System.out.println("original=" + original); System.out.println("copy=" + copy); } }
Employee類代碼以下:
1 package clone; 2 3 import java.util.Date; 4 import java.util.GregorianCalendar; 5 //建立深拷貝的clone方法的一個例子 6 public class Employee implements Cloneable //Employee類實現接口 7 { 8 private String name; 9 private double salary; 10 private Date hireDay; 11 12 public Employee(String name, double salary) 13 { 14 this.name = name; 15 this.salary = salary; 16 hireDay = new Date(); 17 } 18 19 //容許全部方法克隆對象 20 public Employee clone() throws CloneNotSupportedException //將clone從新定義爲public 21 { 22 // call Object.clone() 23 Employee cloned = (Employee) super.clone(); //爲clone方法指定正確的返回類型 24 25 // clone mutable fields 26 cloned.hireDay = (Date) hireDay.clone(); //克隆對象中可變的實例域 27 28 return cloned; 29 } 30 31 /** 32 * Set the hire day to a given date. 33 * @param year the year of the hire day 34 * @param month the month of the hire day 35 * @param day the day of the hire day 36 */ 37 public void setHireDay(int year, int month, int day) 38 { 39 Date newHireDay = new GregorianCalendar(year, month - 1, day).getTime(); 40 41 // example of instance field mutation 42 hireDay.setTime(newHireDay.getTime()); 43 } 44 45 public void raiseSalary(double byPercent) 46 { 47 double raise = salary * byPercent / 100; 48 salary += raise; 49 } 50 51 public String toString() //toString方法 52 { 53 return "Employee[name=" + name + ",salary=" + salary + ",hireDay=" + hireDay + "]"; 54 } 55 }
運行結果以下:
實驗小結:
克隆時,對於每個類,須要肯定:
1)默認的clone方法是否知足要求;
2)是否能夠在可變的子對象上調用clone來修補默認的clone方法;
3)是否不應使用clone
實際上第3個選項是默認的選項。若是選擇第1項或者第2項,類必須:
1)實現Cloneable接口;
2)從新定義clone方法,並指定public訪問修飾符。
3)默認的克隆操做是「淺拷貝」,並無克隆對象中引用的其餘對象。
4)從新定義clone方法來創建一個深拷貝,同時克隆全部子對象。
實驗2: 導入第6章示例程序6-6,學習Lambda表達式用法。
1) 調試運行教材233頁-234頁程序6-6,結合程序運行結果理解程序;
2)在程序中相關代碼處添加新知識的註釋。
3)將27-29行代碼與教材223頁程序對比,將27-29行代碼與此程序對比,體會Lambda表達式的優勢。
LambdaTest代碼以下:
package lambda; import java.util.*; import javax.swing.*; import javax.swing.Timer; /** * This program demonstrates the use of lambda expressions. * @version 1.0 2015-05-12 * @author Cay Horstmann */ public class LambdaTest { public static void main(String[] args) { var planets = new String[] { "Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune" }; //構建一個數組並進行初始化 System.out.println(Arrays.toString(planets)); System.out.println("Sorted in dictionary order:"); Arrays.sort(planets); //調用Arrays的sort方法 System.out.println(Arrays.toString(planets)); System.out.println("Sorted by length:"); Arrays.sort(planets, (first, second) -> first.length() - second.length()); //Lambda表達式 System.out.println(Arrays.toString(planets)); //Lambda表達式轉化爲接口 var timer = new Timer(1000, event -> System.out.println("The time is " + new Date())); timer.start(); // keep program running until user selects "OK" JOptionPane.showMessageDialog(null, "Quit program?"); System.exit(0); } }
代碼運行結果以下:
實驗小結:
1)Lambda表達式是一個可傳遞的代碼塊,能夠在之後執行一次或者屢次
2)Lambda表達式能夠轉換爲接口,使用Lambda表達式要比以前使用傳統的內聯類相比,高效的多。
實驗3: 編程練習
1) 編制一個程序,將身份證號.txt 中的信息讀入到內存中;
2)按姓名字典序輸出人員信息;
3)查詢最大年齡的人員信息;
4)查詢最小年齡人員信息;
5)輸入你的年齡,查詢身份證號.txt中年齡與你最近人的姓名、身份證號、年齡、性別和出生地;
6)查詢人員中是否有你的同鄉。
所寫的代碼以下:
1 package peopleId; 2 3 4 import java.io.BufferedReader; 5 import java.io.File; 6 import java.io.FileInputStream; 7 import java.io.FileNotFoundException; 8 import java.io.IOException; 9 import java.io.InputStreamReader; 10 import java.util.ArrayList; 11 import java.util.Scanner; 12 import java.util.Collections; 13 14 public class Main { 15 16 public static People findPeopleByname(String name) { 17 People flag = null; 18 for (People people : peoplelist) { 19 if(people.getName().equals(name)) { 20 flag = people; 21 } 22 } 23 return flag; 24 25 } 26 27 public static People findPeopleByid(String id) { 28 People flag = null; 29 for (People people : peoplelist) { 30 if(people.getnumber().equals(id)) { 31 flag = people; 32 } 33 } 34 return flag; 35 36 } 37 38 private static ArrayList<People> agenear(int yourage) { 39 // TODO Auto-generated method stub 40 int j=0,min=53,d_value,k = 0; 41 ArrayList<People> plist = new ArrayList<People>(); 42 for (int i = 0; i < peoplelist.size(); i++) { 43 d_value = peoplelist.get(i).getage() > yourage ? 44 peoplelist.get(i).getage() - yourage : yourage - peoplelist.get(i).getage() ; 45 k = d_value < min ? i : k; 46 min = d_value < min ? d_value : min; 47 } 48 for(People people : peoplelist) { 49 if(people.getage() == peoplelist.get(k).getage()) { 50 plist.add(people); 51 } 52 } 53 return plist; 54 } 55 56 private static ArrayList<People> peoplelist; 57 58 public static void main(String[] args) { 59 peoplelist = new ArrayList<People>(); 60 Scanner scanner = new Scanner(System.in); 61 File file = new File("D:\\身份證號.txt"); 62 try { 63 FileInputStream files = new FileInputStream(file); 64 BufferedReader in = new BufferedReader(new InputStreamReader(files)); 65 String temp = null; 66 while ((temp = in.readLine()) != null) { 67 68 String[] information = temp.split("[ ]+"); 69 People people = new People(); 70 people.setName(information[0]); 71 people.setnumber(information[1]); 72 int A = Integer.parseInt(information[3]); 73 people.setage(A); 74 people.setsex(information[2]); 75 for(int j = 4; j<information.length;j++) { 76 people.setplace(information[j]); 77 } 78 peoplelist.add(people); 79 80 } 81 } catch (FileNotFoundException e) { 82 System.out.println("文件未找到"); 83 e.printStackTrace(); 84 } catch (IOException e) { 85 System.out.println("文件讀取錯誤"); 86 e.printStackTrace(); 87 } 88 boolean isTrue = true; 89 while (isTrue) { 90 91 92 System.out.println(" 1.按姓名字典序輸出人員信息"); 93 System.out.println(" 2.查詢最大年齡人員信息"); 94 System.out.println(" 3.查詢最小年齡人員信息"); 95 System.out.println(" 4.輸入你的年齡,查詢身份證號.txt中年齡與你最近的人的姓名、身份證號、年齡、性別和出生地"); 96 System.out.println(" 5.查詢人員中是否有你的同鄉"); 97 System.out.println(" 6.退出"); 98 int nextInt = scanner.nextInt(); 99 switch (nextInt) { 100 case 1: 101 Collections.sort(peoplelist); 102 System.out.println(peoplelist.toString()); 103 break; 104 case 2: 105 int max=0; 106 int j,k1 = 0; 107 for(int i=1;i<peoplelist.size();i++) 108 { 109 j = peoplelist.get(i).getage(); 110 if(j>max) 111 { 112 max = j; 113 k1 = i; 114 } 115 116 } 117 System.out.println("年齡最大:"+peoplelist.get(k1)); 118 break; 119 case 3: 120 int min = 100; 121 int j1,k2 = 0; 122 for(int i=1;i<peoplelist.size();i++) 123 { 124 j1 = peoplelist.get(i).getage(); 125 if(j1<min) 126 { 127 min = j1; 128 k2 = i; 129 } 130 131 } 132 System.out.println("年齡最小:"+peoplelist.get(k2)); 133 break; 134 case 4: 135 System.out.println("年齡:"); 136 int input_age = scanner.nextInt(); 137 ArrayList<People> plist = new ArrayList<People>(); 138 plist = agenear(input_age); 139 for(People people : plist) { 140 System.out.println(people.toString()); 141 } 142 break; 143 case 5: 144 System.out.println("請輸入省份"); 145 String find = scanner.next(); 146 for (int i = 0; i <peoplelist.size(); i++) 147 { 148 String [] place = peoplelist.get(i).getplace().split("\t"); 149 for(String temp : place) { 150 if(find.equals(temp)) { 151 System.out.println("你的同鄉是 "+peoplelist.get(i)); 152 break; 153 } 154 155 156 157 158 } 159 160 } 161 break; 162 case 6: 163 isTrue = false; 164 System.out.println("Goodbye!"); 165 break; 166 default: 167 System.out.println("輸入有誤"); 168 } 169 } 170 } 171 172 }
People類實現接口的代碼以下:
1 package peopleId; 2 3 public class People implements Comparable<People> { 4 5 private String name; 6 private String number; 7 private int age; 8 private String sex; 9 private String place; 10 11 public String getName() 12 { 13 return name; 14 } 15 public void setName(String name) 16 { 17 this.name = name; 18 } 19 public String getnumber() 20 { 21 return number; 22 } 23 public void setnumber(String number) 24 { 25 this.number = number; 26 } 27 public int getage() 28 { 29 return age; 30 } 31 public void setage(int age ) 32 { 33 this.age = age; 34 } 35 public String getsex() 36 { 37 return sex; 38 } 39 public void setsex(String sex ) 40 { 41 this.sex = sex; 42 } 43 public String getplace() 44 { 45 return place; 46 } 47 public void setplace(String place) 48 { 49 if(this.place == null) { 50 this.place = place; 51 }else { 52 this.place = this.place+ "\t" +place; 53 } 54 55 } 56 public int compareTo(People o) 57 { 58 return this.name.compareTo(o.getName()); 59 } 60 public String toString() 61 { 62 return name+"\t"+sex+"\t"+age+"\t"+number+"\t"+place+"\n"; 63 } 64 }
程序結果運行以下:
實驗總結:經過本週的學習我收益不少,好比,知道了接口和繼承之間的區別,object類的clone方法以及lambda表達式等。本週的實驗主要仍是以理解課本中的代碼案例爲主,老師爲了節省咱們的時間,自主完成實驗雖然只是在之前實驗的基礎上添加了新的知識內容,可是本身在完成編程設計時仍是不太熟悉,設計起來比較艱難。