王海珍 201771010124 《面向物件程式設計(java)》第八週實驗總結
第一部分:理論知識
一、介面、lambda和內部類; Comparator與comparable介面;
1.comparable介面的方法是compareTo,只有一個引數;comparator介面的方法是compare,有兩個引數。
comparator自定義比較器。comparable實現介面。
2.物件克隆
1 深拷貝與淺拷貝。如果物件是不可變的,那麼預設的淺拷貝也沒有問題;否則,就要使用深拷貝。
2)預設的克隆方法是淺拷貝,clone方法是Object的一個protected方法。
3) 要讓一個物件可以克隆,則需要如下步驟:
a.實現cloneable介面
b.重定義clone方法,並指定public訪問修飾符。
c.重定義的clone方法要逐一拷貝每一個域。
4.如果一個要clone的物件沒有實現cloneable介面,那麼編譯器就會丟擲一個CloneNotSupportedException異常。
形似cloneable這樣的介面叫做標記介面,標記介面沒有實現任何的方法,他的作用只是允許在型別查詢中使用instanceOf。
即便預設淺拷貝能夠滿足要求,還是徐亞需要實現Cloneable介面,將clone重新定義為public,再呼叫super.clone().
5.lambda表示式
1) 傳程式碼而非傳值。
2) lambda的語法規則:(引數)->以及一個表示式
3)如果計算無法在一個表示式中完成,那麼就使用{}。
4)即使lambda沒有引數,任然要提供空括號,就算無參方法一樣。
5)如果可以推匯出一個lambda表示式的引數型別,則可以忽略其型別。
6)如果方法只要一個引數,而且這個 引數的型別可以推導得出,那麼甚至可以省略小括號。
6)無需指定lambda表示式的返回型別。lambda表示式返回型別總可以由上下文推匯出。
7)如果一個lambda表示式只在某些分支返回一個值,而在另一些分支不返回,這是不合法的。
8)只有一個抽象方法的介面,稱為函式式介面。
9)lambda表示式中捕獲的變數必須是最終變數,這個變數初始化之後就不能再為他賦新值,不能做更改。
10)在lambda表示式中,宣告一個與區域性變數同名的引數或區域性變數是不可合法的。
11)在一個lambda表示式中使用this關鍵字,是指建立這個lambda表示式的方法的this引數。
6.內部類
作用:內部類方法可以訪問外圍類的資料,包括私有的資料.
內部類可以對同一個包種的其他類隱藏起來.
使用anonymous內部類定義回撥函式類.
第二部分:實驗部分
1、實驗目的與要求
(1) 掌握介面定義方法;
(2) 掌握實現介面類的定義要求;
(3) 掌握實現了介面類的使用要求;
(4) 掌握程式回撥設計模式;
(5) 掌握Comparator介面用法;
(6) 掌握物件淺層拷貝與深層拷貝方法;
(7) 掌握Lambda表示式語法;
(8) 瞭解內部類的用途及語法要求。
2、實驗內容和步驟
實驗1: 匯入第6章示例程式,測試程式並進行程式碼註釋。
測試程式1:
l 編輯、編譯、除錯執行閱讀教材214頁-215頁程式6-1、6-2,理解程式並分析程式執行結果;
l 在程式中相關程式碼處新增新知識的註釋。
l 掌握介面的實現用法;
l 掌握內建介面Compareable的用法。
package interfaces; 2 3 public class Employee implements Comparable<Employee> 4 { 5 //宣告屬性; 6 private String name; 7 private double salary; 8 //構造方法; 9 public Employee(String name, double salary) 10 { 11 this.name = name; 12 this.salary = salary; 13 } 14 //Name屬性訪問器; 15 public String getName() 16 { 17 return name; 18 } 19 //Salary屬性訪問器; 20 public double getSalary() 21 { 22 return salary; 23 } 24 //計算工資方法; 25 public void raiseSalary(double byPercent) 26 { 27 double raise = salary * byPercent / 100; 28 salary += raise; 29 } 30 31 /** 32 * Compares employees by salary 33 * @param other another Employee object 34 * @return a negative value if this employee has a lower salary than 35 * otherObject, 0 if the salaries are the same, a positive value otherwise 36 */ 37 38 public int compareTo(Employee other)//compareTo方法; 39 { 40 return Double.compare(salary, other.salary);//包裝器 呼叫compare方法; 41 } 42 }
package interfaces; 2 3 import java.util.*; 4 5 /** 6 * This program demonstrates the use of the Comparable interface. 7 * @version 1.30 2004-02-27 8 * @author Cay Horstmann 9 */ 10 public class EmployeeSortTest 11 { 12 public static void main(String[] args) 13 { 14 //構建陣列物件; 15 Employee[] staff = new Employee[3]; 16 //用三個staff物件填充陣列; 17 staff[0] = new Employee("Harry Hacker", 35000); 18 staff[1] = new Employee("Carl Cracker", 75000); 19 staff[2] = new Employee("Tony Tester", 38000); 20 21 Arrays.sort(staff);//按字母排序方法; 22 23 // print out information about all Employee objects 24 for (Employee e : staff) 25 System.out.println("name=" + e.getName() + ",salary=" + e.getSalary()); 26 } 27 }
測試結果如下所示
測試程式2:
l 編輯、編譯、除錯以下程式,結合程式執行結果理解程式;
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 }
public interface A 2 { 3 double g=9.8; 4 void show( ); 5 } 6 7 8 9 10 public class C implements A 11 { 12 public void show( ) 13 {System.out.println("g="+g);} 14 } 19 public class InterfaceTest 20 { 21 public static void main(String[ ] args) 22 { 23 A a=new C( ); 24 a.show( ); 25 System.out.println("g="+C.g); 26 } 27 }
測試結果如下所示
測試程式3:
l 在elipse IDE中除錯執行教材223頁6-3,結合程式執行結果理解程式;
l 26行、36行程式碼參閱224頁,詳細內容涉及教材12章。
l 在程式中相關程式碼處新增新知識的註釋。
l 掌握回撥程式設計模式;
package timer; 2 3 /** 4 @version 1.01 2015-05-12 5 @author Cay Horstmann 6 */ 7 8 import java.awt.*; 9 import java.awt.event.*; 10 import java.util.*; 11 import javax.swing.*; 12 import javax.swing.Timer; 13 // 解決與java.util.Timer的矛盾 14 15 public class TimerTest 16 { 17 public static void main(String[] args) 18 { 19 ActionListener listener = new TimePrinter(); 20 21 //構造一個呼叫偵聽器的計時器; 22 //每十秒一次; 23 Timer t = new Timer(10000, listener); 24 t.start(); 25 26 JOptionPane.showMessageDialog(null, "Quit program?"); 27 System.exit(0); 28 } 29 } 30 31 class TimePrinter implements ActionListener 32 { 33 public void actionPerformed(ActionEvent event) 34 { 35 System.out.println("At the tone, the time is " + new Date()); 36 Toolkit.getDefaultToolkit().beep(); 37 } 38 }
測試結果如下所示
測試程式4:
l 除錯執行教材229頁-231頁程式6-4、6-5,結合程式執行結果理解程式;
l 在程式中相關程式碼處新增新知識的註釋。
l 掌握物件克隆實現技術;
l 掌握淺拷貝和深拷貝的差別。
package clone; 2 3 import java.util.Date; 4 import java.util.GregorianCalendar; 5 6 public class Employee implements Cloneable 7 { 8 9 private String name; 10 private double salary; 11 private Date hireDay; 12 13 public Employee(String name, double salary) 14 { 15 this.name = name; 16 this.salary = salary; 17 hireDay = new Date(); 18 } 19 // 20 public Employee clone() throws CloneNotSupportedException 21 { 22 23 Employee cloned = (Employee) super.clone();//返回Object物件後強制型別轉換; 24 25 // 克隆可變部分; 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 // 例項欄位變異例項; 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() 52 { 53 return "Employee[name=" + name + ",salary=" + salary + ",hireDay=" + hireDay + "]"; 54 } 55 }
測試結果如下所示
實驗2: 匯入第6章示例程式6-6,學習Lambda表示式用法。
l 除錯執行教材233頁-234頁程式6-6,結合程式執行結果理解程式;
l 在程式中相關程式碼處新增新知識的註釋。
l 將27-29行程式碼與教材223頁程式對比,將27-29行程式碼與此程式對比,體會Lambda表示式的優點。
package Lambda; 2 3 import java.util.*; 4 5 import javax.swing.*; 6 import javax.swing.Timer; 7 8 /** 9 * This program demonstrates the use of lambda expressions. 10 * @version 1.0 2015-05-12 11 * @author Cay Horstmann 12 */ 13 public class LambdaTest 14 { 15 public static void main(String[] args) 16 { 17 //定義並初始化string類陣列; 18 String[] planets = new String[] { "Mercury", "Venus", "Earth", "Mars", 19 "Jupiter", "Saturn", "Uranus", "Neptune" }; 20 //排序前輸出; 21 System.out.println(Arrays.toString(planets)); 22 System.out.println("Sorted in dictionary order:"); 23 Arrays.sort(planets); 24 System.out.println(Arrays.toString(planets));//按字母順序排序輸出; 25 System.out.println("Sorted by length:"); 26 //按單詞長度排序後,使用lambda表示式; 27 Arrays.sort(planets, (first, second) -> first.length() - second.length()); 28 System.out.println(Arrays.toString(planets));// 29 //方法引用;lambda表示式; 30 Timer t = new Timer(1000, event -> 31 System.out.println("The time is " + new Date()));//每隔一秒輸出當前時間; 32 t.start(); 33 34 // 繼續執行程式,知道使用者選擇OK; 35 JOptionPane.showMessageDialog(null, "Quit program?"); 36 System.exit(0); 37 } 38 }
測試結果如下所示
實驗3: 程式設計練習
l 編制一個程式,將身份證號.txt 中的資訊讀入到記憶體中;
l 按姓名字典序輸出人員資訊;
l 查詢最大年齡的人員資訊;
l 查詢最小年齡人員資訊;
l 輸入你的年齡,查詢身份證號.txt中年齡與你最近人的姓名、身份證號、年齡、性別和出生地;
l 查詢人員中是否有你的同鄉。
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.Collections; import java.util.Scanner; public class M{ private static ArrayList<Test> studentlist; public static void main(String[] args) { studentlist = new ArrayList<>(); Scanner scanner = new Scanner(System.in); File file = new File("D:\\身份證號.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 number = linescanner.next(); String sex = linescanner.next(); String age = linescanner.next(); String province =linescanner.nextLine(); Test student = new Test(); student.setName(name); student.setnumber(number); student.setsex(sex); int a = Integer.parseInt(age); student.setage(a); student.setprovince(province); studentlist.add(student); } } 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:退出"); String m = scanner.next(); switch (m) { case "1": Collections.sort(studentlist); System.out.println(studentlist.toString()); break; case "2": int max=0,min=100; int j,k1 = 0,k2=0; for(int i=1;i<studentlist.size();i++) { j=studentlist.get(i).getage(); if(j>max) { max=j; k1=i; } if(j<min) { min=j; k2=i; } } System.out.println("年齡最大:"+studentlist.get(k1)); System.out.println("年齡最小:"+studentlist.get(k2)); break; case "3": System.out.println("province?"); String find = scanner.next(); String place=find.substring(0,3); for (int i = 0; i <studentlist.size(); i++) { if(studentlist.get(i).getprovince().substring(1,4).equals(place)) System.out.println("province"+studentlist.get(i)); } break; case "4": System.out.println("年齡:"); int yourage = scanner.nextInt(); int near=agematched(yourage); int value=yourage-studentlist.get(near).getage(); System.out.println(""+studentlist.get(near)); break; case "5": isTrue = false; System.out.println("退出程式!"); break; default: System.out.println("輸入有誤"); } } } public static int agematched(int age) { int j=0,min=53,value=0,k=0; for (int i = 0; i < studentlist.size(); i++) { value=studentlist.get(i).getage()-age; if(value<0) value=-value; if (value<min) { min=value; k=i; } } return k; } } M
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.Collections; import java.util.Scanner; public class M{ private static ArrayList<Test> studentlist; public static void main(String[] args) { studentlist = new ArrayList<>(); Scanner scanner = new Scanner(System.in); File file = new File("D:\\身份證號.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 number = linescanner.next(); String sex = linescanner.next(); String age = linescanner.next(); String province =linescanner.nextLine(); Test student = new Test(); student.setName(name); student.setnumber(number); student.setsex(sex); int a = Integer.parseInt(age); student.setage(a); student.setprovince(province); studentlist.add(student); } } 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:退出"); String m = scanner.next(); switch (m) { case "1": Collections.sort(studentlist); System.out.println(studentlist.toString()); break; case "2": int max=0,min=100; int j,k1 = 0,k2=0; for(int i=1;i<studentlist.size();i++) { j=studentlist.get(i).getage(); if(j>max) { max=j; k1=i; } if(j<min) { min=j; k2=i; } } System.out.println("年齡最大:"+studentlist.get(k1)); System.out.println("年齡最小:"+studentlist.get(k2)); break; case "3": System.out.println("province?"); String find = scanner.next(); String place=find.substring(0,3); for (int i = 0; i <studentlist.size(); i++) { if(studentlist.get(i).getprovince().substring(1,4).equals(place)) System.out.println("province"+studentlist.get(i)); } break; case "4": System.out.println("年齡:"); int yourage = scanner.nextInt(); int near=agematched(yourage); int value=yourage-studentlist.get(near).getage(); System.out.println(""+studentlist.get(near)); break; case "5": isTrue = false; System.out.println("退出程式!"); break; default: System.out.println("輸入有誤"); } } } public static int agematched(int age) { int j=0,min=53,value=0,k=0; for (int i = 0; i < studentlist.size(); i++) { value=studentlist.get(i).getage()-age; if(value<0) value=-value; if (value<min) { min=value; k=i; } } return k; } } M
實驗4:內部類語法驗證實驗
實驗程式1:
l 編輯、除錯執行教材246頁-247頁程式6-7,結合程式執行結果理解程式;
l 瞭解內部類的基本用法。
package innerClass; 2 3 import java.awt.*; 4 import java.awt.event.*; 5 import java.util.*; 6 import javax.swing.*; 7 import javax.swing.Timer; 8 9 /** 10 * This program demonstrates the use of inner classes. 11 * @version 1.11 2015-05-12 12 * @author Cay Horstmann 13 */ 14 public class InnerClassTest 15 { 16 public static void main(String[] args) 17 { 18 TalkingClock clock = new TalkingClock(1000, true); 19 clock.start(); 20 21 // 保持程式執行知道使用者選擇OK; 22 JOptionPane.showMessageDialog(null, "Quit program?"); 23 System.exit(0); 24 } 25 } 26 27 /** 28 * A clock that prints the time in regular intervals. 29 */ 30 class TalkingClock 31 { 32 private int interval; 33 private boolean beep; 34 35 /** 36 * Constructs a talking clock 37 * @param interval the interval between messages (in milliseconds) 38 * @param beep true if the clock should beep 39 */ 40 public TalkingClock(int interval, boolean beep) 41 { 42 this.interval = interval; 43 this.beep = beep; 44 } 45 46 /** 47 * Starts the clock. 48 */ 49 public void start() 50 { 51 ActionListener listener = new TimePrinter(); 52 Timer t = new Timer(interval, listener); 53 t.start(); 54 } 55 56 public class TimePrinter implements ActionListener 57 { 58 public void actionPerformed(ActionEvent event) 59 { 60 System.out.println("At the tone, the time is " + new Date()); 61 if (beep) Toolkit.getDefaultToolkit().beep(); 62 } 63 } 64 }
實驗程式3:
l 在elipse IDE中除錯執行教材257頁-258頁程式6-9,結合程式執行結果理解程式;
l 瞭解靜態內部類的用法
package staticInnerClass; 2 3 /** 4 * This program demonstrates the use of static inner classes. 5 * @version 1.02 2015-05-12 6 * @author Cay Horstmann 7 */ 8 public class StaticInnerClassTest 9 { 10 public static void main(String[] args) 11 { 12 double[] d = new double[20]; 13 for (int i = 0; i < d.length; i++) 14 d[i] = 100 * Math.random(); 15 ArrayAlg.Pair p = ArrayAlg.minmax(d); 16 System.out.println("min = " + p.getFirst()); 17 System.out.println("max = " + p.getSecond()); 18 } 19 } 20 21 class ArrayAlg 22 { 23 /** 24 * A pair of floating-point numbers 25 */ 26 public static class Pair 27 { 28 private double first; 29 private double second; 30 31 /** 32 * Constructs a pair from two floating-point numbers 33 * @param f the first number 34 * @param s the second number 35 */ 36 public Pair(double f, double s) 37 { 38 first = f; 39 second = s; 40 } 41 42 /** 43 * Returns the first number of the pair 44 * @return the first number 45 */ 46 public double getFirst() 47 { 48 return first; 49 } 50 51 /** 52 * Returns the second number of the pair 53 * @return the second number 54 */ 55 public double getSecond() 56 { 57 return second; 58 } 59 } 60 61 /** 62 * Computes both the minimum and the maximum of an array 63 * @param values an array of floating-point numbers 64 * @return a pair whose first element is the minimum and whose second element 65 * is the maximum 66 */ 67 public static Pair minmax(double[] values) 68 { 69 double min = Double.POSITIVE_INFINITY; 70 double max = Double.NEGATIVE_INFINITY; 71 for (double v : values) 72 { 73 if (min > v) min = v; 74 if (max < v) max = v; 75 } 76 return new Pair(min, max); 77 } 78 }
實驗程式2:
l 編輯、除錯執行教材254頁程式6-8,結合程式執行結果理解程式;
l 瞭解匿名內部類的用法。
import java.awt.*; 2 import java.awt.event.*; 3 import java.util.*; 4 import javax.swing.*; 5 import javax.swing.Timer; 6 7 /** 8 * This program demonstrates anonymous inner classes. 9 * @version 1.11 2015-05-12 10 * @author Cay Horstmann 11 */ 12 public class AnonymousInnerClassTest 13 { 14 public static void main(String[] args) 15 { 16 TalkingClock clock = new TalkingClock(); 17 clock.start(1000, true); 18 19 // 保持程式執行知道使用者選擇OK; 20 JOptionPane.showMessageDialog(null, "Quit program?"); 21 System.exit(0); 22 } 23 } 24 25 /** 26 * A clock that prints the time in regular intervals. 27 */ 28 class TalkingClock 29 { 30 /** 31 * Starts the clock. 32 * @param interval the interval between messages (in milliseconds) 33 * @param beep true if the clock should beep 34 */ 35 //匿名內部類; 36 public void start(int interval, boolean beep) 37 { 38 ActionListener listener = new ActionListener() 39 { 40 public void actionPerformed(ActionEvent event) 41 { 42 System.out.println("At the tone, the time is " + new Date()); 43 if (beep) Toolkit.getDefaultToolkit().beep(); 44 } 45 }; 46 Timer t = new Timer(interval, listener); 47 t.start(); 48 } 49 }
三 實驗總結
本章主要學習了掌握介面定義方法;實現介面類的定義要求;實現了介面類的使用要求;程式回撥設計模式;Comparator介面用法;物件淺層拷貝與深層拷貝方法;Lambda表示式語法;內部類的用途及語法要求。並知道了object類的clone方法,通過學長在群裡的講解明白了介面和繼承之間的區別。在今後會更加努力。