zoukankan      html  css  js  c++  java
  • 第八次实验

    实验六 接口的定义与使用

    实验时间 2018-10-18

    基础知识:

     一  接口:用interface声明,是抽象方法和常量值定义的集 合。从本质上讲,接口是一种特殊的抽象类。

    (1)在Java程序设计语言中,接口不是类,而是对类 的一组需求描述,由常量和一组抽象方法组成。 接口中不包括变量和有具体实现的方法。

    (2)接口体中包含常量定义和方法定义,接口中只进 行方法的声明,不提供方法的实现。

    (3)通常接口的名字以able或ible结尾;

    (4)接口中的所有常量必须是public static final,方法必须是public abstract,这是 系统默认的,不管你在定义接口时,写不写 修饰符都是一样的.

    (5)接口的实现:一个类使用了某个接口,那么这个类必须实现该 接口的所有方法,即为这些方法提供方法体。一个类可以实现多个接口,接口间应该用逗号分 隔开。

    (6)接口的使用:接口不能构造接口对象,但可以声明接口变量以指向一个实现了该接口的类对象。

    (7)可以用instanceof检查对象是否实现了某个接口。

    (8)抽象类:用abstract来声明,没有具体实例对象的类,不 能用new来创建对象。

    二 接口示例 

    (1)回调(callback):一种程序设计模式,在这种模 式中,可指出某个特定事件发生时程序应该采取 的动作。

    (2)Comparator接口所在包: java.util.*

    (3)Object类的Clone方法:当拷贝一个对象变量时,原始变量与拷贝变量 引用同一个对象。这样,改变一个变量所引用 的对象会对另一个变量产生影响。

    (4)如果要创建一个对象新的copy,它的最初状态与 original一样,但以后可以各自改变状态,就需 要使用Object类的clone方法。

    (5)Object.clone()方法返回一个Object对象。必须进行强 制类型转换才能得到需要的类型。

    (6)浅层拷贝与深层拷贝

    (7)Java中对象克隆的实现:在子类中实现Cloneable接口。

    (8)在子类的clone方法中,调用super.clone()。

    三 lambda表达式

    (1)Java Lambda 表达式是 Java 8 引入的一个新的功能,主 要用途是提供一个函数化的语法来简化编码。

    (2)Lambda 表达式的语法基本结构 (arguments) -> body

    (3)有如下几种情况: 1、参数类型可推导时,不需要指定类型,如 (a) -> System.out.println(a)  

    2、 只有一个参数且类型可推导时,不强制写 (), 如 a -> System.out.println(a)    

    3、 参数指定类型时,必须有括号,如 (int a) -> System.out.println(a)    

    4、参数可以为空,如 () -> System.out.println(“hello”)    

    5、 body 需要用 {} 包含语句,当只有一条语句时 {} 可省略

    四   内部类:是定义在一个类内部的类。

    (1)使用内部类的原因有以下三个: –内部类方法可以访问该类定义所在的作用域中 的数据,包括私有数据。

    –内部类能够隐藏起来,不为同一包中的其他类 所见。

    –想要定义一个回调函数且不想编写大量代码时, 使用匿名内部类比较便捷。

    (2)内部类可以直接访问外部类的成员,包括 private成员,但是内部类的成员却不能被外部 类直接访问。

    (3)内部类并非只能在类内定义,也可以在程序块内 定义局部内部类。

    (4)如果构造参数的闭圆括号跟一个开花括号,表明正 在定义的就是匿名内部类。

    实验内容

    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的用法。

     1 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       Employee[] staff = new Employee[3];  //emploee对象数组
    15 
    16       staff[0] = new Employee("Harry Hacker", 35000);
    17       staff[1] = new Employee("Carl Cracker", 75000);
    18       staff[2] = new Employee("Tony Tester", 38000);
    19 
    20       Arrays.sort(staff);   //sort为静态方法(排序)
    21 
    22       //输出所有雇员的信息
    23       for (Employee e : staff)
    24          System.out.println("name=" + e.getName() + ",salary=" + e.getSalary());
    25    }               //按工资的多少排序
    26 }
     1 package interfaces;
     2 
     3 public class Employee implements Comparable<Employee>//employee为用户自定义类,Comparable为接口名,实现了jdk的内置接口
     4 {
     5    private String name;
     6    private double salary;    //属性
     7 
     8    public Employee(String name, double salary)
     9    {
    10       this.name = name;
    11       this.salary = salary;
    12    }           //构造器
    13 
    14    public String getName()
    15    {
    16       return name;
    17    }           //访问器
    18 
    19    public double getSalary()
    20    {
    21       return salary;
    22    }           //访问器
    23 
    24    public void raiseSalary(double byPercent)
    25    {
    26       double raise = salary * byPercent / 100;
    27       salary += raise;
    28    }             //完成涨工资的计算
    29 
    30    /**
    31     * Compares employees by salary
    32     * @param other another Employee object
    33     * @return a negative value if this employee has a lower salary than
    34     * otherObject, 0 if the salaries are the same, a positive value otherwise
    35     */
    36    public int compareTo(Employee other)   //comparable接口的compareTo方法,返回一个整型数值
    37    {
    38       return Double.compare(salary, other.salary);   //double包装器的compare方法
    39    }
    40 }

    测试程序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 在程序中相关代码处添加新知识的注释。

     1 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 // to resolve conflict with java.util.Timer
    14 
    15 public class TimerTest
    16 {  
    17    public static void main(String[] args)
    18    {  
    19        //构造这个类的一个对象,并把它传给timer构造器
    20       ActionListener listener = new TimePrinter();
    21 
    22       // 构造调用侦听器的计时器
    23       // 每十秒钟一次
    24       Timer t = new Timer(10000, listener);
    25       
    26       t.start();//启动定时器
    27        //程序将弹出一个消息对话框
    28       JOptionPane.showMessageDialog(null, "Quit program?");
    29       System.exit(0);
    30    }
    31 }
    32 
    33 class TimePrinter implements ActionListener  //类为TimePrinter,接口为ActionListener,此为内置接口,并无需定义
    34 {  
    35    public void actionPerformed(ActionEvent event)  //当到达指定的时间间隔时。定时器就调用actionPerformed方法,为抽象方法
    36    {  
    37       System.out.println("At the tone, the time is " + new Date());
    38       Toolkit.getDefaultToolkit().beep();//①通过类名调用静态方法,返回值为toolkit对象②toolkit对象再调用beep方法
    39    }
    40 }

    l 掌握回调程序设计模式;

    l回调(callback):一种程序设计模式,在这种模 式中,可指出某个特定事件发生时程序应该采取 的动作。
    在java.swing包中有一个Timer类,可以使用它 在到达给定的时间间隔时触发一个事件。
    –Timer(intinterval,ActionListenerlistener)
    –voidstart()
    –voidstop()

    测试程序4:

    l 调试运行教材229页-231页程序6-4、6-5,结合程序运行结果理解程序;

    l 在程序中相关代码处添加新知识的注释。

     1 package clone;
     2 
     3 import java.util.Date;
     4 import java.util.GregorianCalendar;
     5 
     6 public class Employee implements Cloneable
     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    public Employee clone() throws CloneNotSupportedException
    20    {
    21       // call Object.clone()
    22       Employee cloned = (Employee) super.clone();
    23 
    24       // clone mutable fields
    25       cloned.hireDay = (Date) hireDay.clone();
    26 
    27       return cloned;
    28    }            //抛出异常
    29 
    30    /**
    31     * Set the hire day to a given date. 
    32     * @param year the year of the hire day
    33     * @param month the month of the hire day
    34     * @param day the day of the hire day
    35     */
    36    public void setHireDay(int year, int month, int day)
    37    {
    38       Date newHireDay = new GregorianCalendar(year, month - 1, day).getTime();
    39       
    40       // 实例字段突变示例
    41       hireDay.setTime(newHireDay.getTime());
    42    }
    43 
    44    public void raiseSalary(double byPercent)
    45    {
    46       double raise = salary * byPercent / 100;
    47       salary += raise;
    48    }             //完成涨工资的计算
    49 
    50    public String toString()
    51    {
    52       return "Employee[name=" + name + ",salary=" + salary + ",hireDay=" + hireDay + "]";
    53    }
    54 }
     1 package clone;
     2 
     3 /**
     4  * This program demonstrates cloning.
     5  * @version 1.10 2002-07-01
     6  * @author Cay Horstmann
     7  */
     8 public class CloneTest
     9 {
    10    public static void main(String[] args)
    11    {
    12       try
    13       {
    14          Employee original = new Employee("John Q. Public", 50000);
    15          original.setHireDay(2000, 1, 1);
    16          Employee copy = original.clone();
    17          copy.raiseSalary(10);
    18          copy.setHireDay(2002, 12, 31);
    19          System.out.println("original=" + original);
    20          System.out.println("copy=" + copy);
    21       }
    22       catch (CloneNotSupportedException e)
    23       {
    24          e.printStackTrace();    //异常处理
    25       }
    26    }
    27 }

    l 掌握对象克隆实现技术;

    l 掌握浅拷贝和深拷贝的差别。

    浅层拷贝:被拷贝对象的所有常量成员和基本类 型属性都有与原来对象相同的拷贝值,而若成员 域是一个对象,则被拷贝对象该对象域的对象引 用仍然指向原来的对象。 l深层拷贝:被拷贝对象的所有成员域都含有与原 来对象相同的值,且对象域将指向被复制过的新对 象,而不是原有对象被引用的对象。换言之,深 层拷贝将拷贝对象内引用的对象也拷贝一遍。

    实验2: 导入第6章示例程序6-6,学习Lambda表达式用法。

    l 调试运行教材233页-234页程序6-6,结合程序运行结果理解程序;

    l 在程序中相关代码处添加新知识的注释。

    l 将27-29行代码与教材223页程序对比,将27-29行代码与此程序对比,体会Lambda表达式的优点。

     1 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[] planets = new String[] { "Mercury", "Venus", "Earth", "Mars", 
    18             "Jupiter", "Saturn", "Uranus", "Neptune" };
    19       System.out.println(Arrays.toString(planets));
    20       System.out.println("Sorted in dictionary order:");
    21       Arrays.sort(planets);    //按字典顺序对planets排序
    22       System.out.println(Arrays.toString(planets));
    23       System.out.println("Sorted by length:");
    24       Arrays.sort(planets, (first, second) -> first.length() - second.length());
    25       System.out.println(Arrays.toString(planets));//lambda表达式,按字符串长度对planets排序
    26             
    27       Timer t = new Timer(1000, event ->
    28          System.out.println("The time is " + new Date()));    //lambda表达式
    29       t.start();   
    30          
    31       // 保持程序运行直到用户选择ok
    32 JOptionPane.showMessageDialog(null, "Quit program?"); 33 System.exit(0); 34 } 35 }

    注:以下实验课后完成

    实验3: 编程练习

    l 编制一个程序,将身份证号.txt 中的信息读入到内存中;

    l 按姓名字典序输出人员信息;

    l 查询最大年龄的人员信息;

    l 查询最小年龄人员信息;

    l 输入你的年龄,查询身份证号.txt中年龄与你最近人的姓名、身份证号、年龄、性别和出生地;

    l 查询人员中是否有你的同乡。

    代码如下

      1 package xinxi;
      2 
      3 import java.io.BufferedReader;
      4 import java.io.File;
      5 import java.io.FileInputStream;
      6 import java.io.FileNotFoundException;
      7 import java.io.IOException;
      8 import java.io.InputStreamReader;
      9 import java.util.ArrayList;
     10 import java.util.Arrays;
     11 import java.util.Collections;
     12 import java.util.Scanner;
     13 
     14 public class xinxi{
     15     private static ArrayList<Student> studentlist;
     16     public static void main(String[] args) {
     17         studentlist = new ArrayList<>();
     18         Scanner scanner = new Scanner(System.in);
     19         File file = new File("F:\身份证号.txt");
     20         try {
     21             FileInputStream fis = new FileInputStream(file);
     22             BufferedReader in = new BufferedReader(new InputStreamReader(fis));
     23             String temp = null;
     24             while ((temp = in.readLine()) != null) {
     25                 
     26                 Scanner linescanner = new Scanner(temp);
     27                 
     28                 linescanner.useDelimiter(" ");    
     29                 String name = linescanner.next();
     30                 String number = linescanner.next();
     31                 String sex = linescanner.next();
     32                 String age = linescanner.next();
     33                 String province =linescanner.nextLine();
     34                 Student student = new Student();
     35                 student.setName(name);
     36                 student.setnumber(number);
     37                 student.setsex(sex);
     38                 int a = Integer.parseInt(age);
     39                 student.setage(a);
     40                 student.setprovince(province);
     41                 studentlist.add(student);
     42 
     43             }
     44         } catch (FileNotFoundException e) {
     45             System.out.println("学生信息文件找不到");
     46             e.printStackTrace();
     47         } catch (IOException e) {
     48             System.out.println("学生信息文件读取错误");
     49             e.printStackTrace();
     50         }
     51         boolean isTrue = true;
     52         while (isTrue) {
     53             System.out.println("输入序号进行相应的操作");
     54             System.out.println("1.字典排序");
     55             System.out.println("2.输出年龄最大和年龄最小的人");
     56             System.out.println("3.查找与你年龄相近的人");
     57             System.out.println("4.查找你的同乡");
     58             String n = scanner.next();
     59             switch (n) {
     60             case "1":
     61                 Collections.sort(studentlist);              
     62                 System.out.println(studentlist.toString());
     63                 break;
     64             case "2":
     65                  int max=0,min=100;
     66                  int j,k1 = 0,k2=0;
     67                  for(int i=1;i<studentlist.size();i++)
     68                  {
     69                      j=studentlist.get(i).getage();
     70                  if(j>max)
     71                  {
     72                      max=j; 
     73                      k1=i;
     74                  }
     75                  if(j<min)
     76                  {
     77                    min=j; 
     78                    k2=i;
     79                  }
     80                  
     81                  }  
     82                  System.out.println("年龄最大:"+studentlist.get(k1));
     83                  System.out.println("年龄最小:"+studentlist.get(k2));
     84                 break;
     85             case "3":
     86                 System.out.println("年龄:");
     87                 int yourage = scanner.nextInt();
     88                 int near=agenear(yourage);
     89                 int value=yourage-studentlist.get(near).getage();
     90                 System.out.println("和你年龄相近的是"+studentlist.get(near));
     91                 break;
     92 
     93             case "4":
     94                  System.out.println("输入你的家乡");
     95                  String find = scanner.next();        
     96                  String place=find.substring(0,3);
     97                  for (int i = 0; i <studentlist.size(); i++) 
     98                  {
     99                      if(studentlist.get(i).getprovince().substring(1,4).equals(place)) 
    100                          System.out.println("你的同乡是  "+studentlist.get(i));
    101                  }             
    102                  break;
    103 
    104             }
    105         }
    106     }
    107         public static int agenear(int age) {      
    108         int j=0,min=53,value=0,k=0;
    109          for (int i = 0; i < studentlist.size(); i++)
    110          {
    111              value=studentlist.get(i).getage()-age;
    112              if(value<0) value=-value; 
    113              if (value<min) 
    114              {
    115                 min=value;
    116                 k=i;
    117              } 
    118           }    
    119          return k;         
    120       
    121 
    122 }
    123 
    124 
    125 }
     1 package xinxi;
     2 
     3 
     4 
     5 public class Student implements Comparable<Student> {
     6 
     7     private String name;
     8     private String number ;
     9     private String sex ;
    10     private int age;
    11     private String province;
    12    
    13     public String getName() {
    14         return name;
    15     }
    16     public void setName(String name) {
    17         this.name = name;
    18     }
    19     public String getnumber() {
    20         return number;
    21     }
    22     public void setnumber(String number) {
    23         this.number = number;
    24     }
    25     public String getsex() {
    26         return sex ;
    27     }
    28     public void setsex(String sex ) {
    29         this.sex =sex ;
    30     }
    31     public int getage() {
    32 
    33         return age;
    34         }
    35     public void setage(int age) {
    36         this.age= age;
    37         }
    38 
    39     public String getprovince() {
    40         return province;
    41     }
    42     public void setprovince(String province) {
    43         this.province=province ;
    44     }
    45 
    46     public int compareTo(Student o) {
    47        return this.name.compareTo(o.getName());
    48     }
    49 
    50     public String toString() {
    51         return  name+"	"+sex+"	"+age+"	"+number+"	"+province+"
    ";
    52     }    
    53 }

    实验结果如下图

    实验4内部类语法验证实验

    实验程序1:

    l 编辑、调试运行教材246页-247页程序6-7,结合程序运行结果理解程序;

    l 了解内部类的基本用法。

    实验程序2:

    l 编辑、调试运行教材254页程序6-8,结合程序运行结果理解程序;

    l 了解匿名内部类的用法。

    实验程序3:

    l 在elipse IDE中调试运行教材257页-258页程序6-9,结合程序运行结果理解程序;

    l 了解静态内部类的用法。

    实验总结

    掌握了接口的定义用法;掌握了实现接口类的定义要求和使用要,对程序回调设计模式和Comparator接口用法也有相应的了解与程序的理解。

    在老师及助教学长的引领下,关于对象浅层拷贝与深层拷贝方法了解的相当透彻,自己也通过书籍和网上的精彩帖子了解到更多。

    此外对Lambda表达式语法和内部类的用途及语法要求做了相应的了解。

    最后,关于此次的编程任务,是建立在前几次的读取txt文件实验的内容上做了相应的拓展,完成的较为理想,对程序理解的也很透彻,但还是有些不了解的地方,通过网上搜寻和向同学提问也得到了相应的解答,最终解决了问题,得出最终结果。相较前几次实验有所提高,还需继续努力。

  • 相关阅读:
    CSS之旅——第二站 如何更深入的理解各种选择器
    CSS之旅——第一站 为什么要用CSS
    记录一些在用wcf的过程中走过的泥巴路 【第一篇】
    asp.net mvc 之旅—— 第二站 窥探Controller下的各种Result
    asp.net mvc 之旅—— 第一站 从简单的razor入手
    Sql Server之旅——终点站 nolock引发的三级事件的一些思考
    Sql Server之旅——第十四站 深入的探讨锁机制
    Sql Server之旅——第十三站 对锁的初步认识
    Sql Server之旅——第十二站 sqltext的参数化处理
    Sql Server之旅——第十一站 简单说说sqlserver的执行计划
  • 原文地址:https://www.cnblogs.com/zyan---/p/9812174.html
Copyright © 2011-2022 走看看