201871010124-王生濤 《面向對象程序設計(java)》第八週學習總結

博文正文開頭格式:(2分)html

項目java

內容express

這個做業屬於哪一個課程編程

 https://www.cnblogs.com/nwnu-daizh/設計模式

這個做業的要求在哪裏數組

   https://www.cnblogs.com/nwnu-daizh/p/11435127.htmldom

做業學習目標函數

  1. (1) 掌握接口定義方法;工具

    (2) 掌握實現接口類的定義要求;學習

    (3) 掌握實現了接口類的使用要求;

    (4) 掌握程序回調設計模式;

    (5) 掌握Comparator接口用法;

    (6) 掌握對象淺層拷貝與深層拷貝方法;

    (7) 掌握Lambda表達式語法;

    (8) 瞭解內部類的用途及語法要求。

第一部分:總結第五章理論知識(30分)

Java中類於類之間的關係以及代碼示例:
1、繼承關係

繼承指的是一個類(稱爲子類、子接口)繼承另外的一個類(稱爲父類、父接口)的功能,並能夠增長它本身的新功能的能力。在Java中繼承關係經過關鍵字extends明確標識,在設計時通常沒有爭議性。在UML類圖設計中,繼承用一條帶空心三角箭頭的實線表示,從子類指向父類,或者子接口指向父接口。 
2、實現關係

實現指的是一個class類實現interface接口(能夠是多個)的功能,實現是類與接口之間最多見的關係。在Java中此類關係經過關鍵字implements明確標識,在設計時通常沒有爭議性。在UML類圖設計中,實現用一條帶空心三角箭頭的虛線表示,從類指向實現的接口。 
3、依賴關係

簡單的理解,依賴就是一個類A使用到了另外一個類B,而這種使用關係是具備偶然性的、臨時性的、很是弱的,可是類B的變化會影響到類A。好比某人要過河,須要借用一條船,此時人與船之間的關係就是依賴。表如今代碼層面,爲類B做爲參數被類A在某個method方法中使用。在UML類圖設計中,依賴關係用由類A指向類B的帶箭頭虛線表示。
4、關聯關係

關聯體現的是兩個類之間語義級別的一種強依賴關係,好比我和個人朋友,這種關係比依賴更強、不存在依賴關係的偶然性、關係也不是臨時性的,通常是長期性的,並且雙方的關係通常是平等的。關聯能夠是單向、雙向的。表如今代碼層面,爲被關聯類B以類的屬性形式出如今關聯類A中,也多是關聯類A引用了一個類型爲被關聯類B的全局變量。在UML類圖設計中,關聯關係用由關聯類A指向被關聯類B的帶箭頭實線表示,在關聯的兩端能夠標註關聯雙方的角色和多重性標記。
5、聚合關係

聚合是關聯關係的一種特例,它體現的是總體與部分的關係,即has-a的關係。此時總體與部分之間是可分離的,它們能夠具備各自的生命週期,部分能夠屬於多個總體對象,也能夠爲多個總體對象共享。好比計算機與CPU、公司與員工的關係等,好比一個航母編隊包括海空母艦、驅護艦艇、艦載飛機及核動力攻擊潛艇等。表如今代碼層面,和關聯關係是一致的,只能從語義級別來區分。在UML類圖設計中,聚合關係以空心菱形加實線箭頭表示。 
6、組合關係

組合也是關聯關係的一種特例,它體現的是一種contains-a的關係,這種關係比聚合更強,也稱爲強聚合。它一樣體現總體與部分間的關係,但此時總體與部分是不可分的,總體的生命週期結束也就意味着部分的生命週期結束,好比人和人的大腦。表如今代碼層面,和關聯關係是一致的,只能從語義級別來區分。在UML類圖設計中,組合關係以實心菱形加實線箭頭表示。 
    注意: 繼承與實現是類於類,或者類與接口之間的一種縱向關係,其餘的四種關係體現的是類和類、或者類與接口間的引用、橫向關係,是比較難區分的,有不少事物間的關係要想準肯定位是很難的。前面也提到,這四種關係都是語義級別的,因此從代碼層面並不能徹底區分各類關係,但總的來講,後幾種關係所表現的強弱程度依次爲:組合>聚合>關聯>依賴。
一、接口:Java爲了克服單繼承的特色,Java使用了接口,一個類能夠實現一個或者多個接口;
二、在Java中,接口不是類,而是對類的一組需求描述 ,由常量和一組抽象方法組成;
三、接口中不包括變量和具體方法的實現;
四、只要類實現了接口,則該類要聽從接口描述的統一格式進行定義,而且能夠在任何須要接口的地方使用這個類得額對象;
五、接口的類型:
用戶自定義接口;
標準接口;
一、自定義接口的聲明:
(1)聲明方式: public interface 接口名
{······}
(2)接口體中包含常量定義和抽象方法的定義 ,接口中只進行方法的聲明,不提供實現的方法;
二、相似創建類的繼承關係,接口也能夠擴展;
三、接口的擴展技術使得從具備較高通用性的接口存在多條鏈延伸到具備較高專用性的接口;
四、擴展方法:
public interface 接口1 extends 接口2
{······ }
說明:(1)一般接口的名字以able或者ible結尾;
(2)能夠經過extends來繼承接口的常量和抽象方法,擴展造成新的接口;
(3)接口中的全部常量必須都是 public static final,方法必須是public abstract ,這是系統默認的,寫不寫修飾符都是同樣的;
五、接口的實現:
(1)在類聲明時用implements關鍵字來聲明使用一個或者多個接口
class Employee implements Printable
{······ }
(2)一個類使用了某個接口,那麼這個類必須實現該接口的全部方法,即爲這些方法提供方法體;
(3)一個類能夠實現多個接口,接口間應該用逗號隔開。
class Employee implements Cloneable , Comparable
說明:(1)若實現接口的類不是抽象類,則必須實現全部接口的全部方法,即爲全部的抽象方法定義方法體;
           (2)一個類在實現某接口方法時,必須使用徹底相同的方法名、參數列表和返回值類型;
           (3)接口抽象方法的訪問控制符已指定爲 public,因此類在實現時,必須顯示的使用public修飾符,不然被警告縮小了接口中定義的方法的訪問控制範圍;
六、接口的使用:
(1)接口不能構造接口對象,但能夠聲明接口變量以指向一個實現了該接口的類對象;
Comparable x = new Comparable(······ ) //錯誤
Comparable x = new Employee(······ ) //正確
(2)能夠用instanceof來檢查對象是否實現了某個接口
if (anObject instanceof Comparable)
{······ }
七、接口與抽象類:
(1)抽象類:用abstract來聲明,沒有具體實例對象的類,不能用new來建立對象。可包含常規類所包含的任何東西,抽象類必須由子類繼承,若是abstract類的子類不是抽象類,那麼子類必須重寫父類中的全部的abstract方法;
(2)接口:用interface來聲明,是抽象方法和常量值構成的集合。從本質上來說,接口是一種特殊的抽象類,這種抽象類中只包含常量和抽象方法的定義,而沒有變量和方法的定義,接口中只能定義抽象方法,並且這些方法默認爲public的,只要類實現了接口,就能夠在任何須要該接口的地方使用這個類的對象。此外,一個類能夠實現多個接口。
八、接口與抽象類的區別:
(1)接口不能實現任何方法,而抽象類能夠;
(2)類能夠實現不少接口,但只有一個父類;
(3)接口不是一個類分級結構中的一部分,無任何聯繫的類能夠實現相同的接口。
6.2 接口示例
接口與回調
(1)回調:(callback):一種程序設計模式,在這種模式中,可指出某個特定事件發生時,程序應該採起的動做;
(2)在Java.Swing包中有一個Timer類,可使用它在到達給定的時間間隔時觸發的一個事件。
Comparable接口:
用途(1):處理字符串按長度進行排序的操做;
對象克隆:
一、object類當中 的clone方法:
(1)當拷貝一個對象變量時,原始變量與拷貝變量引用同一個對象,這樣,改變一個變量所引用的對象會對另外一個變量產生影響;
(2)若是要建立一個對象新的copy,它的最初狀態與original同樣,但之後能夠各自改變狀態,就須要使用clone方法;
(3)object類中的clone()方法是一個native方法;
(4)object類中的clone()方法被protected修飾符修飾,着覺得着在用戶編寫的代碼中不能直接調用它。若是要直接應用clone()方法,就須要覆蓋clone()方法,並要把clone()方法的屬性設置爲public;
(5)object類中的clone()方法返回一個object對象,必須進行強制轉換類型才能獲得須要的類型;
二、淺層拷貝和深層拷貝
(1)淺層拷貝:被拷貝對象的全部常量成員和基本類型屬性都有與原來對象相同的拷貝值,而若成員域是一個對象,則被拷貝對象該對象魚的對象引用仍然指向原來的對象;
(2)深層拷貝:被拷貝對象的全部成員域都含有與原來對象相同的拷貝值,且對象域將指向被複制過的新對象,而不是原來對象被引用的而對象。
想要實現深層拷貝,必須克隆類中全部的對象的實例域。
三、Java中克隆對象的實現:
對象克隆要點:
(1)在子類中實現Cloneable接口;
(2)爲了獲取對象的一份拷貝,能夠利用Object類的clone方法;
(3)在子類中覆蓋超類的clone方法,聲明爲public;
(4)在子類的clone方法中,調用super.clone();
四、public interface Cloneable{
}
能夠看到,這個內置接口Cloneable是空的,它僅僅是一個標誌,這樣的接口稱爲標誌接口,且這個接口只針對Object類的clone()方法;
若是一個類沒有實現Cloneable接口,且調用了Object類的clone()方法(即調用了super.clone()方法),那麼Object類的clone方法就會拋出CloneNotSupportedException 異常。
接口學習中的幾個問題:
一、精簡程序結構,免除代碼的重複使用;
(1)若是有兩個及以上的類擁有相同的方法,可是實現功能不同,就能夠定義一個接口(抽象類),將這個方法提煉出來,在須要使用該方法的類中去實現,就免除了多個類定義系統方法的麻煩;
(2)因爲Java只支持單繼承,若是被提煉的方法定義爲抽象類,若某個類要擴展兩個以上這樣的抽象類就會被限制,則這時就能夠定義爲接口。
6·三、Lambda表達式:主要是提供一個函數化的語法來簡化編碼。
(1)Lambda表達式本質上是一個匿名方法。
  public int add(int x, int y){
  return x + y;} 將其轉成Lambda表達式爲: (int x , int y) -> x + y;
參數類型能夠省略,Java編譯器會根據上下文推斷出來:
(x, y)-> x + y; //返回兩數之和
(x, y)->{return x + y;} //顯式指明返回值
(2)Lambda表達式的語法基本結構: (arguments)-> body
有以下幾種狀況:
a、參數類型可推導時,不須要指定類型;eg: (a)->System.out.println(a)
b、只有一個參數且類型可推導時,不強制寫(), eg:a->System.out.println(a)
c、參數指定類型時,必須有括號, eg:(int a) -> System.out.println(a)
d、參數能夠爲空,eg:()-> System.out.println("Hello")
e、body須要用{}包含語句,當只有一條語句時{}能夠省略。
(3)函數式接口Functionalinterface
a、Java Lambda表達式以函數式接口爲應用基礎;
b、函數式接口,只有一個方法的接口,這類接口的目的是爲了一個單一的操做;
c、函數式接口用做表示Lambda表達式的類型。
(4)建立函數式接口:
有時候須要自定義一個函數式接口,作法也很簡單,首先此接口只能有一個函數操做,而後在接口操做類型上標註註解@Functionalinterface便可
6·4 內部類
(1)內部類(inner class )是定義在一個類內部的類;
(2)外層的類稱爲外部類(outer class);
(3)內部類主要用於處理事件;
(4)使用內部類的緣由:
a、內部類方法能夠訪問該類定義所在的做用域中的數據,包括私有數據;
b、內部類可以隱藏起來,不爲同一包中的其餘類可見;
c、想要定義一個回調函數且不想編寫大量的代碼時,使用匿名內部類比較便捷;
(5)內部類的聲明:
class outerClass{
【修飾符】class inner Class{
...........
}
...........
}
內部類能夠直接訪問外部類的成員,包括private成員,可是內部類的成員卻不能被外部類直接訪問;

二、實驗內容和步驟

實驗1: 導入第6章示例程序,測試程序並進行代碼註釋。

測試程序1:

l  編輯、編譯、調試運行閱讀教材214頁-215頁程序6-一、6-2,理解程序並分析程序運行結果;

l  在程序中相關代碼處添加新知識的註釋。

l  掌握接口的實現用法;

l  掌握內置接口Compareable的用法。

實驗代碼以下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package  interfaces;
 
public  class  Employee  implements  Comparable<Employee>    //接口的定義,Comparable是內置接口
{
    private  String name;      //私有變量的定義
    private  double  salary;
 
    public  Employee(String name,  double  salary)     //Employee構造器
    {
       this .name = name;
       this .salary = salary;
    }
 
    public  String getName()       //getName方法訪問器
    {
       return  name;
    }
 
    public  double  getSalary()      //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)     //按工資輸出
    {
       return  Double.compare(salary, other.salary);    
    }
}

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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     //EmployeeSortTest類
{
    public  static  void  main(String[] args)
    {
       Employee[] staff =  new  Employee[ 3 ];    //Employee對象數組的建立  
 
       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)      //調用getNname()方法以及getSalary()方法輸出全部僱員的信息
          System.out.println( "name="  + e.getName() +  ",salary="  + e.getSalary());
    }
}

  運行結果以下:

測試程序2:

l  編輯、編譯、調試如下程序,結合程序運行結果理解程序;

  代碼以下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
interface   A     //A接口
{
   double  g= 9.8 ;   
   void  show( );   
}
class  implements  A        //定義C繼承接口A
{
   public  void  show( )
   {
       System.out.println( "g=" +g);     //將g的值輸出在控制檯上
   }
}
 
class  InterfaceTest      //InterfaceTest類的定義
{
   public  static  void  main(String[ ] args)
   {
        A a= new  C( );  
        a.show( );
        System.out.println( "g=" +C.g);     //輸出g的值在控制檯上
   }
}

運行結果以下:

l  在elipse IDE中調試運行教材223頁6-3,結合程序運行結果理解程序;測試程序3:

實驗代碼以下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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)
   
       ActionListener listener =  new  TimePrinter();     //構造這個類的一個對象,並將它傳遞給Timer構造器
       //ActionListener接口對象,建立實現類接口的對象
       // construct a timer that calls the listener
       // once every second
       Timer timer =  new  Timer( 1000 , listener);     //建立定時器類對象timer
       timer.start();       //啓動定時器
 
       // keep program running until the user selects "OK"
       JOptionPane.showMessageDialog( null "Quit program?" );     //啓動程序後,將會當即彈出一個包含"Quit program?"字樣的對話框
       System.exit( 0 );
    }
}
 
class  TimePrinter  implements  ActionListener    //接口
    public  void  actionPerformed(ActionEvent event)    //actionPerformed方法的ActionEvent參數,提供了事件的相關信息
   
       System.out.println( "At the tone, the time is "
          + Instant.ofEpochMilli(event.getWhen()));     //每隔10秒,這條信息就會輸出一次,而後響一聲鈴
       Toolkit.getDefaultToolkit().beep();     //返回Toolkit,調用getDefaultToolkit()方法,得到默認的工具箱
    }
}

  運行結果以下:

l  26行、36行代碼參閱224頁,詳細內容涉及教材12章。

l  在程序中相關代碼處添加新知識的註釋。

l  掌握回調程序設計模式;

測試程序4:

l  調試運行教材229頁-231頁程序6-四、6-5,結合程序運行結果理解程序;

l  在程序中相關代碼處添加新知識的註釋。

l  掌握對象克隆實現技術;

l  掌握淺拷貝和深拷貝的差異。

實驗代碼以下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
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)     //Employee構造器
    {
       this .name = name;
       this .salary = salary;
       hireDay =  new  Date();
    }
 
    public  Employee clone()  throws  CloneNotSupportedException  
    //聲明異常,在一個對象上調用clone,但這個 對象的類並無實現Cloneable的接口,而後Object類的clone方法就會拋出一個 CloneNotSupportedException。
    {
       // call Object.clone()
       Employee cloned = (Employee)  super .clone();
 
       // clone mutable fields
       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();
       
       // example of instance field mutation
       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 +  "]" ;
    }
}

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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
    {
       Employee original =  new  Employee( "John Q. Public" 50000 );
       original.setHireDay( 2000 1 1 );
       Employee copy = original.clone();    
       //原始變量與拷貝變量引用統一個對象,這樣,使用Object類的Clone對象,改變一個對象所引用的對象就不會影響另外一個對象
       copy.raiseSalary( 10 );      //copy會增加10%的薪資,可是original不會變
       copy.setHireDay( 2002 12 31 );
       System.out.println( "original="  + original);
       System.out.println( "copy="  + copy);
    }
}

  運行結果以下:

淺層拷貝和深層拷貝的差異:

(1)淺層拷貝:被拷貝對象的全部常量成員和基本類型屬性都有與原來對象相同的拷貝值,而若成員域是一個對象,則被拷貝對象該對象魚的對象引用仍然指向原來的對象;

(2)深層拷貝:被拷貝對象的全部成員域都含有與原來對象相同的拷貝值,且對象域將指向被複制過的新對象,而不是原來對象被引用的而對象。
想要實現深層拷貝,必須克隆類中全部的對象的實例域。

實驗2: 導入第6章示例程序6-6,學習Lambda表達式用法。

l  調試運行教材233頁-234頁程序6-6,結合程序運行結果理解程序;

l  在程序中相關代碼處添加新知識的註釋。

l  將27-29行代碼與教材223頁程序對比,將27-29行代碼與此程序對比,體會Lambda表達式的優勢。

實驗代碼以下:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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     //LambdaTest類
{
    public  static  void  main(String[] args)
    {
       String[] planets =  new  String[] {  "Mercury" "Venus" "Earth" "Mars" ,
          "Jupiter" "Saturn" "Uranus" "Neptune"  };     //建立一個String類數組對象
       System.out.println(Arrays.toString(planets));          //調用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());  //能夠推導出first以及second的類型
       System.out.println(Arrays.toString(planets));
             
       Timer 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 );        
    }
}

  運行結果以下:

實驗2:內部類語法驗證明驗

實驗程序1:

l  編輯、調試運行教材246頁-247頁程序6-7,結合程序運行結果理解程序;

l  瞭解內部類的基本用法。

實驗代碼以下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package  innerClass;
 
import  java.awt.*;
import  java.awt.event.*;
import  java.time.*;
 
import  javax.swing.*;
 
/**
  * This program demonstrates the use of inner classes.
  * @version 1.11 2017-12-14
  * @author Cay Horstmann
  */
public  class  InnerClassTest
{
    public  static  void  main(String[] args)
    {
       TalkingClock clock =  new  TalkingClock( 1000 true );       //建立TalkingClock對象,
       clock.start();        
 
       // keep program running until the user selects "OK"
       JOptionPane.showMessageDialog( null "Quit program?" );      //當程序開始運行的時候當即出現寫有「Quit program」的對話框
       System.exit( 0 );
    }
}
 
/**
  * A clock that prints the time in regular intervals.
  */
class  TalkingClock            //抽象一個TalkingClock類
{
    private  int  interval;        //構造語音時鐘時所須要的兩個參數:發佈通告的間隔以及開關鈴聲的標誌
    private  boolean  beep;
 
    /**
     * Constructs a talking clock
     * @param interval the interval between messages (in milliseconds)
     * @param beep true if the clock should beep
     */
    public  TalkingClock( int  interval,  boolean  beep)              //TalkingClock構造器
    {
       this .interval = interval;
       this .beep = beep;
    }
 
    /**
     * Starts the clock.
     */
    public  void  start()      //方法聲明
    {
       TimePrinter listener =  new  TimePrinter();            //建立一個TimePrinter對象,其在TalkingClock的內部
       Timer timer =  new  Timer(interval, listener);
       timer.start();       //啓動
    }
 
    public  class  TimePrinter  implements  ActionListener      //將TimePrinter類聲明爲實現ActionListener接口
    {
       public  void  actionPerformed(ActionEvent event)       //actionPerformed方法在發出鈴聲以前檢查了beep標誌
       {
          System.out.println( "At the tone, the time is "
             + Instant.ofEpochMilli(event.getWhen()));
          if  (beep) Toolkit.getDefaultToolkit().beep();
       }
    }
}

  運行結過以下:

實驗程序2:

l  編輯、調試運行教材254頁程序6-8,結合程序運行結果理解程序;

l  掌握匿名內部類的用法。

實驗代碼以下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package  anonymousInnerClass;
 
import  java.awt.*;
import  java.awt.event.*;
import  java.time.*;
 
import  javax.swing.*;
 
/**
  * This program demonstrates anonymous inner classes.
  * @version 1.12 2017-12-14
  * @author Cay Horstmann
  */
public  class  AnonymousInnerClassTest
{
    public  static  void  main(String[] args)
    {
       TalkingClock clock =  new  TalkingClock();            //建立一個TalkingClock對象
       clock.start( 1000 true );    
 
       // keep program running until the user selects "OK"
       JOptionPane.showMessageDialog( null "Quit program?" );
       System.exit( 0 );
    }
}
 
/**
  * A clock that prints the time in regular intervals.
  */
class  TalkingClock            //抽象一個TalkingClock類
{
    /**
     * Starts the clock.
     * @param interval the interval between messages (in milliseconds)
     * @param beep true if the clock should beep
     */
    public  void  start( int  interval,  boolean  beep)     //方法聲明
    {
       ActionListener listener =  new  ActionListener()     //建立一個實現ActionListener接口的類的新對象,
          {
             public  void  actionPerformed(ActionEvent event)   //須要實現的方法定義在ActionListener括號{}內
             {
                System.out.println( "At the tone, the time is "
                   + Instant.ofEpochMilli(event.getWhen()));
                if  (beep) Toolkit.getDefaultToolkit().beep();     //在響鈴以前actionPerformed檢查了beep
             }
          };
       Timer timer =  new  Timer(interval, listener);             //建立一個Timer類對象
       timer.start();         //啓動計時器
    }
}

  運行結果以下:

實驗程序3:

l  在elipse IDE中調試運行教材257頁-258頁程序6-9,結合程序運行結果理解程序;

l  瞭解靜態內部類的用法。

實驗代碼以下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package  staticInnerClass;
 
/**
  * This program demonstrates the use of static inner classes.
  * @version 1.02 2015-05-12
  * @author Cay Horstmann
  */
public  class  StaticInnerClassTest
{
    public  static  void  main(String[] args)
    {
       double [] values =  new  double [ 20 ];     //定義一個double對象數組
       for  ( int  i =  0 ; i < values.length; i++)
          values[i] =  100  * Math.random();
       ArrayAlg.Pair p = ArrayAlg.minmax(values);  
       System.out.println( "min = "  + p.getFirst());    //這個方法的調用者可使用getFirst和getSecond方法得到答案
       System.out.println( "max = "  + p.getSecond());
    }
}
 
class  ArrayAlg     //抽象一個ArrayAlg類
{
    /**
     * A pair of floating-point numbers
     */
    public  static  class  Pair      //在Pair對象中不須要引用任何其餘的對象,因此將這個內部類聲明爲static
    {
       private  double  first;     //定義兩個私有變量
       private  double  second;
 
       /**
        * Constructs a pair from two floating-point numbers
        * @param f the first number
        * @param s the second number
        */
       public  Pair( double  f,  double  s)        //Pair構造器
       {
          first = f;
          second = s;
       }
 
       /**
        * Returns the first number of the pair
        * @return the first number
        */
       public  double  getFirst()   //getFirst方法聲明
       {
          return  first;
       }
 
       /**
        * Returns the second number of the pair
        * @return the second number
        */
       public  double  getSecond()        //getSecond方法聲明
       {
          return  second;
       }
    }
 
    /**
     * Computes both the minimum and the maximum of an array
     * @param values an array of floating-point numbers
     * @return a pair whose first element is the minimum and whose second element
     * is the maximum
     */
    public  static  Pair minmax( double [] values)
    //必須使用靜態內部類,由於內部類對象是在靜態方法中定義的,若是沒有將Pair聲明爲static,編譯器會報錯,沒有可用的隱式ArrayAlg類型對象初始化內部對象   
    {
       double  min = Double.POSITIVE_INFINITY;
       double  max = Double.NEGATIVE_INFINITY;
       for  ( double  v : values)
       {
          if  (min > v) min = v;
          if  (max < v) max = v;
       }
       return  new  Pair(min, max);    //minmax必須返回返回一個Pair類型的對象
    }
}

  運行結過以下:

實驗3: 編程練習

l  編制一個程序,將身份證號.txt 中的信息讀入到內存中;

l  按姓名字典序輸出人員信息;

l  查詢最大年齡的人員信息;

l  查詢最小年齡人員信息;

l  輸入你的年齡,查詢身份證號.txt中年齡與你最近人的姓名、身份證號、年齡、性別和出生地;

l  查詢人員中是否有你的同鄉。

實驗代碼以下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
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  IDTest{
     private  static  ArrayList<Student> studentlist;    
     public  static  void  main(String[] args) {
         studentlist =  new  ArrayList<>();
         Scanner scanner =  new  Scanner(System.in);
         File file =  new  File( "D:\\java\\身份證號.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();
                 Student student =  new  Student();
                 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.輸入你的年齡,查詢身份證號.txt中年齡與你最近人的姓名、身份證號、年齡、性別和出生地" );
             System.out.println( "4:按省份找你的同鄉;" );
             System.out.println( "5:退出" );
             String m = scanner.next();
             switch  (m) {
             case  "1" :
                 Collections.sort(studentlist); 
                 System.out.println( "排序後的結果爲:"  "\n" );
                 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( "Max  age:" +studentlist.get(k1));
                  System.out.println( "Min  age:" +studentlist.get(k2));
                 break ;
             case  "3" :
                 System.out.println( "age:" );
                 int  yourage = scanner.nextInt();
                 int  near=agenear(yourage);
                 int  value=yourage-studentlist.get(near).getage();
                 System.out.println( "年齡與你最近的人的姓名、身份證號、年齡、性別和出生地爲:"  "\n" );
                 System.out.println( "" +studentlist.get(near));
                 break ;
             case  "4" :
                 System.out.println( " Which province were you born in?" );
                 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( "查找到的老鄉有:"  "\n"  +studentlist.get(i));
                 }            
                 break ;
                 
             case  "5" :
                 isTrue =  false ;
                 System.out.println( "退出程序!!!!" );
                 break ;
                 default :
                 System.out.println( "信息輸入有誤!!!" );
 
             }
         }
     }
         public  static  int  agenear( 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;        
       }
 
}

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
public  class  Student  implements  Comparable<Student> {     //定義實現Comparable<Student>接口的類Student
 
     private  String name;           //私有變量的定義
     private  String number ;
     private  String sex ;
     private  int  age;
     private  String province;
    
     public  String getName() {           //構造器
         return  name;     
     }
     public  void  setName(String name) {     //訪問器
         this .name = name;
     }
     public  String getnumber() {
         return  number;
     }
     public  void  setnumber(String number) {  
         this .number = number;
     }
     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 getprovince() {
         return  province;
     }
     public  void  setprovince(String province) {
         this .province=province ;
     }
 
     public  int  compareTo(Student o) {        //compareTo方法將會返回一個整型數值
        return  this .name.compareTo(o.getName());
     }
 
     public  String toString() {
         return   name+ "\t" +sex+ "\t" +age+ "\t" +number+ "\t" +province+ "\n" ;
     }   
}

  運行結果以下:

 實驗總結:(10分)

主要了解了接口,接口和繼承在某些方面比較類似,可是接口又在繼承的基礎上發展了一些優勢,克服了java單繼承的缺點。實現接口類的定義要求,實現了接口類的使用要求,理解程序回調設計模式,掌握了Comparator接口用法:對象克隆須要實現Cloneable接口,若是沒有實現Cloneable接口,且調用了Object的clone()方法,就會拋出CloneNotSupportedException異常 ,掌握到對象淺層拷貝與深層拷貝方法瞭解到它們的區別,Lambda表達式語法等等的要求

相關文章
相關標籤/搜索