201871010118-唐敬博《面向对象程序设计(java)》第八周学习总结

博文正文开头格式:(2分)

项目

内容

这个作业属于哪个课程

https://www.cnblogs.com/nwnu-daizh/

这个作业的要求在哪里

https://www.cnblogs.com/lily-2018/p/11441372.html

作业学习目标

(1) 掌握接口定义方法;

(2) 掌握实现接口类的定义要求;

(3) 掌握实现了接口类的使用要求;

(4) 掌握程序回调设计模式;

(5) 掌握Comparator接口用法;

(6) 掌握对象浅层拷贝与深层拷贝方法;

(7) 掌握Lambda表达式语法;

(8) 了解内部类的用途及语法要求。

随笔博文正文内容包括:

第一部分:总结第六章理论知识(30分)

抽象类:

      用abstract来声明,没有具体实例对象的类,不能用new来创建对象。可包含常规类所包含的任何东西。抽象类必须由子类继承,如果abstract类的子类不是抽象类,那么子类必须重写父类中所有的abstract方法。

接口:

      用interface声明,是抽象方法和常量值定义的集合。从本质上讲,接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的定义,而没有变量和方法的定义。接口中只能定义抽象方法,而且这些方法默认为是public的。只要类实现了接口,就可以在任何需要该接 口的地方使用这个类的对象。此外,一个类可以实现多个接口。

 接口与抽象类的区别:

(1)接口不能实现任何方法,而抽象类可以。 

(2)类可以实现许多接口,但只有一个父类。

(3)接口不是类分级结构的一部分,无任何联系的类可以实现相同的接口。

接口的定义方法:

      在Java程序设计语言中,接口不是类,而是对类的一组需求描述,由常量和一组抽象方法组成。接口中不包括变量和有具体实现的方法。只要类实现了接口,则该类要遵从接口描述的统一格式进行定义,并且可以在任何需要该接口的地方使用这个类的对象。

接口的实现:

        类声明时用implements关键字声明使用一个或多个接口,一个类使用了某个接口,那么这个类必须实现,接口的所有方法,即为这些方法提供方法体。
 一个类可以实现多个接口,接口间应该用逗号分隔开。

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

回调(callback):

       一种程序设计模式,在这种模式中,可指出某个特定事件发生时程序应该采取的动作。当拷贝一个对象变量时,原始变量与拷贝变量引用同一个对象。这样,改变一个变量所引用 的对象会对另一个变量产生影响。如果要创建一个对象新的copy,它的最初状态与 original一样,但以后可以各自改变状态,就需要使用Object类的clone方法。Object类的clone()方法是一个native方法。Object类中的clone()方法被protected修饰符修饰。这意味着在用户编写的代码中不能直接调用它。如果要直接应用clone()方法,就需覆盖clone()方法,并要把clone()方法的属性设置为public。  Object.clone()方法返回一个Object对象。必须进行强制类型转换才能得到需要的类型。

在java.swing包中有一个Timer类,可以使用它在到达给定的时间间隔时触发一个事件。

浅层拷贝:

 被拷贝对象的所有常量成员和基本类型属性都有与原来对象相同的拷贝值,而若成员域是一个对象,则被拷贝对象该对象域的对象引用仍然指向原来的对象。

深层拷贝:

       被拷贝对象的所有成员域都含有与原来对象相同的值,且对象域将指向被复制过的新对象,而不是原有对象被引用的对象。换言之, 深层拷贝将拷贝对象内引用的对象也拷贝一遍 。

 Java中对象克隆的实现:

     在子类中实现Cloneable接口。为了获取对象的一份拷贝,可以利用Object类的clone方法。在子类中覆盖超类的clone方法,声明为public。在子类的clone方法中,调用super.clone()。

1、 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 需要用 {} 包含语句,当只有一条语句时 {} 可省略。

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

使用内部类的原因有以下三个:内部类方法可以访问该类定义所在的作用域中 的数据,包括私有数据。内部类能够隐藏起来,不为同一包中的其他类 所见。

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

      内部类可以直接访问外部类的成员,包括 private成员,但是内部类的成员却不能被外部 类直接访问。内部类并非只能在类内定义,也可以在程序块内 定义局部内部类。如果构造参数的闭圆括号跟一个开花括号,表明正 在定义的就是匿名内部类。

 

第二部分:实验部分

实验1:测试程序1(5分)

1)编辑、编译、调试运行阅读教材214页-215页程序6-1、6-2,理解程序并分析程序运行结果;

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

3)掌握接口的实现用法;掌握内置接口Compareable的用法。

代码如下:

{1}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)
   {
      Employee[] staff = new Employee[3];  //用三个staff对象填充数组;
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()); } }

知识兔
{2}package interfaces;public class Employee implements Comparable<Employee>{
//声明属性; 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) { return Double.compare(salary, other.salary); }}

运行结果如图:

实验1:测试程序2(5分)

编辑、编译、调试以下程序,结合程序运行结果理解程序;

 
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); //C实现了接口A,所以可以用C调用A中的变量
} }

运行结果如图:

实验1:测试程序3(5分)

在elipse IDE中调试运行教材223页6-3,结合程序运行结果理解程序;

l 26行、36行代码参阅224页,详细内容涉及教材12章。

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

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

 程序代码如下:

/**   @version 1.01 2015-05-12   @author Cay Horstmann*/import java.awt.*;import java.awt.event.*;import java.util.*;import javax.swing.*;import javax.swing.Timer; // to resolve conflict with java.util.Timerpublic class TimerTest{     public static void main(String[] args)   {        ActionListener listener = new TimePrinter();      // 构造一个timer对象存放在变量里,叫做listener      // 每次间隔10秒      Timer t = new Timer(10000, listener);      t.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 " + new Date());      Toolkit.getDefaultToolkit().beep();      //每隔10秒响一次   }}
运行结果如图:

实验1:测试程序4(5分)

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

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

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

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

6-4,6-5 代码如下:

{1}package clone;/** * This program demonstrates cloning. * @version 1.10 2002-07-01 * @author Cay Horstmann */public class CloneTest{   public static void main(String[] args)   {      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();      }   }}
{2}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();   }   public Employee clone() throws 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 + "]";   }}
运行结果如下:

实验2:(10分)

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

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

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

3. 将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" };
      //toString方法输出planets对象
      System.out.println(Arrays.toString(planets));
      System.out.println("Sorted in dictionary order:");
      //Arrays.sort方法按照字符顺序排序
      Arrays.sort(planets);
      System.out.println(Arrays.toString(planets));
      System.out.println("Sorted by length:");
      //Arrays.sort方法按照字符串长度排序
      Arrays.sort(planets, (first, second) -> first.length() - second.length());
      System.out.println(Arrays.toString(planets));
             
      //lambda表达式: (argument)-> body
      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:编程练习(25分)

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

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

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

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

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

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

程序代码如下:

{1}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 Main{    private static ArrayList<Student> studentlist;    public static void main(String[] args) {        studentlist = new ArrayList<>();        Scanner scanner = new Scanner(System.in);        File file = new File("C:\\Users\\ASUS\\Desktop\\新建文件夹\\身份证号.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("选择你的操作,输入正确格式的选项");            System.out.println("A.字典排序");            System.out.println("B.输出年龄最大和年龄最小的人");            System.out.println("C.寻找老乡");            System.out.println("D.寻找年龄相近的人");            System.out.println("F.退出");            String m = scanner.next();            switch (m) {            case "A":                Collections.sort(studentlist);                              System.out.println(studentlist.toString());                break;            case "B":                 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 "C":                 System.out.println("老家?");                 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("老乡"+studentlist.get(i));                 }                              break;                             case "D":                System.out.println("年龄:");                int yourage = scanner.nextInt();                int near=agenear(yourage);                int value=yourage-studentlist.get(near).getage();                System.out.println(""+studentlist.get(near));                break;            case "F":                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;               }}

{2}public class Student implements Comparable<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) {            // int a = Integer.parseInt(age);        this.age= age;        }    public String getprovince() {        return province;    }    public void setprovince(String province) {        this.province=province ;    }    public int compareTo(Student o) {       return this.name.compareTo(o.getName());    }    public String toString() {        return  name+"\t"+sex+"\t"+age+"\t"+number+"\t"+province+"\n";    }    }
运行结果如下:

实验总结:(10分)

在本周的学习过程中,主要了解了接口,接口和继承在某些方面比较相似,但是接口又在继承的基础上发展了一些优点,克服了java单继承的缺点。在学习过程中,可能是因为接口并不是具体的类,它只是实现,所以感觉接口比继承抽象一些,不太容易理解。但通过这周的学习以及实验中对具体程序的运行,对接口有了一定的掌握。以后的学习我会更加努力

计算机