201871010111-劉佳華《面向對象程序設計(java)》第八週學習總結java
實驗七 接口的定義與使用express
實驗時間 2019-10-18編程
第一部分:知識總結設計模式
接口的概念:ide
①java爲了克服單繼承的缺點而引入接口。學習
②接口不是類,而是對類的一組需求描述,這類要聽從從接口描述的統一格式進行定義。測試
③一個類能夠實現(implement)一個或多個接口,並在須要接口的地方,隨時實現相應的接口對象。ui
聲明:接口體中包含常量定義和方法定義,接口中只進行方法的聲明,不提供方法的實現。this
說明:spa
1)一般接口的名字以-able或-ible結尾;
2)可使用extends來繼承接口的常量和抽象方法,擴展造成新的接口;
3)接口中的全部常量必須是public static final,方法必須是public abstract,這是系統默認的,無論你在定義接口時,寫不寫修飾符都是同樣的。
接口的實現:在類聲明時使用implement關鍵字實現一個或多個接口(用逗號隔開),且一個類若使用了某個接口,那麼這個類必須實現該個接口的全部方法,即提供方法體。
說明:
(1)若實現接口的類不是抽象類,則必須實現全部接口的全部方法,即爲全部的抽象方法定義方法體。
(2)一個類在實現某接口抽象方法時,必須使用徹底相同的方法名、參數列表和返回值類型。
(3)接口抽象方法的訪問控制符已指定爲public,因此類在實現時,必須顯式地使用public修飾符,不然被警告縮小了接口中定義的方法的訪問控制範圍。
接口的使用:
接口不能構造接口對象,但能夠聲明接口變量以指向一個實現了該接口的類對象。
接口與抽象類:
接口與抽象類的區別:
(1)接口不能實現任何方法,而抽象類能夠。
(2)類能夠實現許多接口,但只有一個父類。
(3)接口不是類分級結構的一部分,無任何聯繫的類能夠實現相同的接口。
掌握CompareTo接口和Comparator接口使用方法
回調的定義與用法
對象克隆:
*Object類的Clone方法
*淺層拷貝與深層拷貝
淺層拷貝:被拷貝對象的全部常量成員和基本類型屬性都有與原來對象相同的拷貝值,而若成員域是一個對象,則被拷貝對象該對象域的對象引用仍然指向原來的對象。
深層拷貝:被拷貝對象的全部成員域都含有與原來對象相同的值,且對象域將指向被複制過的新對象,而不是原有對象被引用的對象。換言之,深層拷貝將拷貝對象內引用的對象也拷貝一遍。
*Java中對象克隆的實現
Lambda表達式:
這是一種表示能夠在未來某個時間點執行代碼塊的簡潔方法。
Lambda表達式的語法基本結構
(arguments) -> body有以下幾種狀況:
●參數類型可推導時,不須要指定類型,如
(a) -> System.out.printin(a)
●只有一個參數且類型可推導時,不強制寫(,如
a一> System.out.printn(a)
, 參數指定類型時,必須有括號,如(int a) -> System.out.printin(a)●參數能夠爲空,如() > System.out.printn("hello"), body須要用{}包含語句,當只有一 條語句時{}可省略
內部類:
●內部類能夠直接訪問外部類的成員保括private成員,可是內部類的成員卻不能被外部類直接訪問。
●在內部類對象保存了一個對外部類對象的引用,當內部類的成員方法中訪問某一變量時, 若是在該方法和內部類中都未定義過這個變裏,內部類中對變裏的引用會被傳遞給外部類對象的引用。
局部內部類
●內部類並不是只能在類內定義,也能夠在程序塊內定義局部內部類。例如,在方法中,甚至在for循環體內部。
●局部內部類不能用publi c或pr ivate訪問修飾符進行聲明,它的做用域被限定在聲明這個局部類的塊中。
匿名內部類
●若只建立類的一個對象,則沒必要爲該類命名,這種類稱爲匿名內部類。
●因爲匿名類沒有類名,因此匿名類不能有構造器,取而代之的是將構造器參數傳遞給超類的構造器。若匿名內部類實現接口時,則匿名內部類不能有任何構造參數。
●若是構造參數的閉圓括號跟一個開花括號,代表正在定義的就是匿名內部類
第二部分:實驗部分
1、實驗目的與要求
(1) 掌握接口定義方法;
(2) 掌握實現接口類的定義要求;
(3) 掌握實現了接口類的使用要求;
(4) 掌握程序回調設計模式;
(5) 掌握Comparator接口用法;
(6) 掌握對象淺層拷貝與深層拷貝方法;
(7) 掌握Lambda表達式語法;
(8) 瞭解內部類的用途及語法要求。
2、實驗內容和步驟
實驗1: 導入第6章示例程序,測試程序並進行代碼註釋。
測試程序1:
l 編輯、編譯、調試運行閱讀教材214頁-215頁程序6-一、6-2,理解程序並分析程序運行結果;
l 在程序中相關代碼處添加新知識的註釋。
l 掌握接口的實現用法;
l 掌握內置接口Compareable的用法。
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);//實現按姓名字符串長度排序操做 // print out information about all Employee objects for (Employee e : staff) System.out.println("name=" + e.getName() + ",salary=" + e.getSalary());//遍歷輸出 } }
package interfaces; public class Employee implements Comparable<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)//接口Comparable的compareTo方法 { return Double.compare(name.length(), other.name.length() ); } }
運行截圖以下:
測試程序2:
l 編輯、編譯、調試如下程序,結合程序運行結果理解程序;
interface A { double g=9.8; void show( ); } class C implements A { public void show( ) {System.out.println("g="+g);} }
class InterfaceTest { public static void main(String[ ] args) { A a=new C( ); a.show( ); System.out.println("g="+C.g); } } |
運行截圖:
測試程序3:
l 在elipse IDE中調試運行教材223頁6-3,結合程序運行結果理解程序;
l 26行、36行代碼參閱224頁,詳細內容涉及教材12章。
l 在程序中相關代碼處添加新知識的註釋。
l 掌握回調程序設計模式;
package timer; /** @version 1.02 2017-12-14 @author Cay Horstmann */ import java.awt.*; import java.util.*; import java.awt.event.*; //import java.time.*; import javax.swing.*; import javax.swing.Timer; public class TimerTest { public static void main(String[] args) { TimePrinter listener = new TimePrinter();//接口對象 // construct a timer that calls the listener // once every second Timer timer = new Timer(1000, listener);//計時器對象(時間間隔(ms),執行listener); timer.start(); // 一直運行程序知道點擊「肯定」; JOptionPane.showMessageDialog(null, "Quit program?");//顯示系統對話框 System.exit(0); } } class TimePrinter implements ActionListener { public void actionPerformed(ActionEvent event) { //System.out.println("At the tone, the time is " // + Instant.ofEpochMilli(event.getWhen())); System.out.println("At the tone, the time is " + new Date()); Toolkit.getDefaultToolkit().beep();//硬件環境參數 } }
運行截圖:
不點「肯定」,每1s,輸出一次結果,而且電腦蜂鳴器響一次
測試程序4:
l 調試運行教材229頁-231頁程序6-四、6-5,結合程序運行結果理解程序;
l 在程序中相關代碼處添加新知識的註釋。
l 掌握對象克隆實現技術;
l 掌握淺拷貝和深拷貝的差異。
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 { ////放入try中,配合後面的語句捕獲異常 try { Employee 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); } catch(CloneNotSupportedException e){ //捕獲異常 e.printStackTrace(); } } }
package clone; import java.util.Date; import java.util.GregorianCalendar; public class Employee implements Cloneable { private String name; private double salary; private Date hireDay; public Employee(String name, double salary) { this.name = name; this.salary = salary; hireDay = new Date(); } @Override protected Employee clone() throws CloneNotSupportedException { // 調用object.clone() Employee cloned = (Employee) super.clone(); // 克隆可變字段 cloned.hireDay = (Date) hireDay.clone(); return cloned; } /** * Set the hire day to a given date. * @param year the year of the hire day * @param month the month of the hire day * @param day the day of the hire day */ public void setHireDay(int year, int month, int day) { Date newHireDay = new GregorianCalendar(year, month - 1, day).getTime(); // 實例字段變異示例 hireDay.setTime(newHireDay.getTime()); } public void raiseSalary(double byPercent) { double raise = salary * byPercent / 100; salary += raise; } public String toString() { return "Employee[name=" + name + ",salary=" + salary + ",hireDay=" + hireDay + "]"; } }
運行截圖:
實驗2: 導入第6章示例程序6-6,學習Lambda表達式用法。
l 調試運行教材233頁-234頁程序6-6,結合程序運行結果理解程序;
l 在程序中相關代碼處添加新知識的註釋。
l 將27-29行代碼與教材223頁程序對比,將27-29行代碼與此程序對比,體會Lambda表達式的優勢。
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); System.out.println(Arrays.toString(planets)); System.out.println("Sorted by length:"); Arrays.sort(planets, (first, second) -> first.length() - second.length()); System.out.println(Arrays.toString(planets)); var timer = new Timer(1000, event -> System.out.println("The time is " + new Date())); timer.start(); // 中止運行直到點擊"OK" JOptionPane.showMessageDialog(null, "Quit program?"); System.exit(0); } }
運行:
注:如下實驗課後完成
實驗3: 編程練習
l 編制一個程序,將身份證號.txt 中的信息讀入到內存中;
l 按姓名字典序輸出人員信息;
l 查詢最大年齡的人員信息;
l 查詢最小年齡人員信息;
l 輸入你的年齡,查詢身份證號.txt中年齡與你最近人的姓名、身份證號、年齡、性別和出生地;
l 查詢人員中是否有你的同鄉。
package T; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Arrays; import java.util.Scanner; import java.util.Collections;//對集合進行排序、查找、修改等; public class Main { private static ArrayList<Citizen> citizenlist; public static void main(String[] args) { citizenlist = new ArrayList<>(); Scanner scanner = new Scanner(System.in); File file = new File("D:\\JAVA2\\WEEK8\\src\\T\\身份證號.txt"); //異常捕獲 try { FileInputStream fis = new FileInputStream(file); BufferedReader in = new BufferedReader(new InputStreamReader(fis)); String temp = null; while ((temp = in.readLine()) != null) { Scanner linescanner = new Scanner(temp); linescanner.useDelimiter(" "); String name = linescanner.next(); String id = linescanner.next(); String sex = linescanner.next(); String age = linescanner.next(); String birthplace = linescanner.nextLine(); Citizen citizen = new Citizen(); citizen.setName(name); citizen.setId(id); citizen.setSex(sex); // 將字符串轉換成10進制數 int ag = Integer.parseInt(age); citizen.setage(ag); citizen.setBirthplace(birthplace); citizenlist.add(citizen); } } catch (FileNotFoundException e) { System.out.println("信息文件找不到"); e.printStackTrace(); } catch (IOException e) { System.out.println("信息文件讀取錯誤"); e.printStackTrace(); } boolean isTrue = true; while (isTrue) { System.out.println("1.按姓名字典序輸出人員信息"); System.out.println("2.查詢最大年齡的人員信息、查詢最小年齡人員信息"); System.out.println("3.查詢人員中是否有你的同鄉"); System.out.println("4.輸入你的年齡,查詢文件中年齡與你最近人的姓名、身份證號、年齡、性別和出生地"); System.out.println("5.退出"); int nextInt = scanner.nextInt(); switch (nextInt) { case 1: Collections.sort(citizenlist);//按name字典序排序 System.out.println(citizenlist.toString()); break; case 2: int max = 0, min = 100; int m, k1 = 0, k2 = 0; for (int i = 1; i < citizenlist.size(); i++) { m = citizenlist.get(i).getage(); if (m > max) { max = m; k1 = i; } if (m < min) { min = m; k2 = i; } } System.out.println("年齡最大:" + citizenlist.get(k1)); System.out.println("年齡最小:" + citizenlist.get(k2)); break; case 3: System.out.println("出生地:"); String find = scanner.next(); String place = find.substring(0, 3); for (int i = 0; i < citizenlist.size(); i++) { if (citizenlist.get(i).getBirthplace().substring(1, 4).equals(place)) System.out.println("出生地" + citizenlist.get(i)); } break; case 4: System.out.println("年齡:"); int yourage = scanner.nextInt(); int near = peer(yourage); int j = yourage - citizenlist.get(near).getage(); System.out.println("" + citizenlist.get(near)); break; case 5: isTrue = false; System.out.println("程序已退出!"); break; default: System.out.println("輸入有誤"); } } } public static int peer(int age) { int flag = 0; int min = 53, j = 0; for (int i = 0; i < citizenlist.size(); i++) { j = citizenlist.get(i).getage() - age; if (j < 0) j = -j; if (j < min) { min = j; flag = i; } } return flag; } }
package T; public class Citizen implements Comparable<Citizen> { private String name; private String id; private String sex; private int age; private String birthplace; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public int getage() { return age; } public void setage(int age) { this.age = age; } public String getBirthplace() { return birthplace; } public void setBirthplace(String birthplace) { this.birthplace = birthplace; } public int compareTo(Citizen other) { return this.name.compareTo(other.getName()); } public String toString() { return name + "\t" + sex + "\t" + age + "\t" + id + "\t" + birthplace + "\n"; } }
運行結果:
實驗心得體會:
經過一個周的學習,我大體掌握了接口的概念和實現方法,可以使用接口編寫一些簡單程序,並會使用comparable接口裏的CompareTo和Comparator方法;初步的瞭解了克隆的概念,可是仍有一些小問題(深層拷貝和淺層拷貝的地方),仍須要學習和老師的講解;還有lambda表達式能夠簡化程序的編寫,使得程序簡潔工整。