zoukankan      html  css  js  c++  java
  • 201871010102常龙龙《面向对象程序设计(java)》第八周学习总结

    项目

    内容

    这个作业属于哪个课程

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

    这个作业的要求在哪里

    https://www.cnblogs.com/nwnu-daizh/p/11703678.html

    作业学习目标

    1. 掌握接口定义方法;
    2. 掌握实现接口类的定义要求;
    3. 掌握实现了接口类的使用要求;
    4. 理解程序回调设计模式;
    5. 掌握Comparator接口用法;
    6. 掌握对象浅层拷贝与深层拷贝方法;
    7. 掌握Lambda表达式语法;
    8. 了解内部类的用途及语法要求。

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

    一、接口

    1.接口技术主要用来描述类具有什么功能,而并不给出每个功能的具体实现。一个类可以实现一个或多个接口,并在需要接口的地方,随时使用实现了相应接口的对象

    ●Java为了克服单继承的缺点,Java使用了接口,一 -个类可以实现-一个或多个接口。
    ●在Java中,接口不是类,而是对类的-组需求描述,由常量和一组抽象方法组成。
    ●接口中不包括变量和有具体实现的方法。
    ●只要类实现了接口,则该类要遵从接口描述的统一 格式进行定义,并且可以在任何需要该接口的地方使用这个类的对象。

    ●接口类型
        1.用户自定义接口

         2.标准接口。

    2.自定义接口的声明 

    1>声明方式:public interface 接口名

    {.....}

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

    3> 说明

    (1) 通常接口的名字以able或ible结尾;
    (2) 可以使用ex tends来继承接口的常量和抽象方法,扩展形成新的接口;
    (3) 接口中的所有常量必须是public static final,方法必须是public abstract,这是系统默认的,不管你在定义接口时,写不写修饰符都是一样的。

    3.接口的实现

    ● 在类声明时用implements关键字声明使用一个或多个接口
    class Employee implements Printable
    { ....... }

    ●一个类使用了某个接口,那么这个类必须实现该接口的所有方法,即为这些方法提供方法体。

    ●一个类可以实现多个接口,接口间应该用逗号分隔开。
    class Employee implements Cl oneable, Comparable

    {.....}

    说明:

    (1)若实现接口的类不是抽象类,则必须实现所有接口的所有方法,即为所有的抽象方法定义方法体。
    (2)一个类在实现某接口抽象方法时,必须使用完全相同的方法名、参数列表和返回值类型。
    (3)接口抽象方法的访问控制符已指定为public,所以类在实现时,必须显式地使用public修饰符,否则被警告缩小了接口中定义的方法的访问控制范围。

    4.接口的使用

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

    Comparable x = new Comparabe() ;//error
    Comparable x= new Employee();  //0K 

    ●可以用instanceof检查对象是否实现了某个接口

         if (an0bject instanceof Comparable)
         { ......}

    5.接口与抽象类的区别:

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

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

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

     二、Lambda表达式

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

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

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

                                     ●参数指定类型时,必须有括号,如(inta)>System.out.println(a)

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

                                     ● body需要用包含语句,当只有一条语句时&可省略;

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

       Lambda表达式本质上是一个匿名方法。

         public int add(int x,int y){returnx+y;}

       转成Lambda表达式后是这个样子:(int x,int y)->x+y;

       参数类型也可以省略,Java编译器会根据上下文推断出来:(x,y)->x+y;//返回两数之和或者(x,y)->{returnx+y;}//显式指明返回值

     三、内部类

    1.内部类(inner class)是定义在一个类内部的类。外层的类成为外部类(outer class).内部类主要用于事件处理。使用内部类的原因:

               ●内部类方法可以访问该类定义所在的作用域中的数据, 包括私有的数据。
               ●内部类可以对同一个包中的其他类隐藏起来。
                ●当想要定义一个回调函数且不想编写大量代码时,使用匿名 (anonymous) 内部类比较便捷。

    2.局部内部类

     ●可以在一个方法中定义局部类,并且不能用public或private访问说明符进行声明,它的作用域被限定在声明这个局部类的块中。

     ●局部类可以对外部世界完全隐藏起来,即使方法所在类中的其他代码也不能访问。除了定义它的方法外,没有任何方法知道它的存在。

     ●局部类的另一个优势:不仅可以访问包含它们的外部类,还可以访问局部变量,但那些局部变量必须被声明为final

    3.匿名内部类

    ●将局部内部类的使用再深人一步。 假如只创建这个类的一个对象,就不必命名了。这种类被称为匿名内部类(anonymous inner class)。

    ●由于构造器的名字必须与类名相同, 而匿名类没有类名, 所以, 匿名类不能有构造器。取而代之的是,将构造器参数传递给超类 ( superclass) 构造器。尤其是在内部类实现接口的时候, 不能有任何构造参数。如果构造参数的闭小括号后面跟一个开大括号, 正在定义的就是匿名内部类 。

    注意:建立一个与超类大体类似(但不完全相同)的匿名子类通常会很方便。不过, 对于 equals 方法要特别当心。

    ●SuperType可以是接口,内部类就要实现这个接口;也可以是一个类,内部类就要扩展它。

    4.静态内部类

    .有时使用内部类只是为了把一个类隐藏在另外一个类的内部,并不需要内部类引用外围类对象。为此,可以将内部类声明为 static, 以便取消产生的引用。 只有内部类可以声明为 static。静态内部类的对象除了没有对生成它的外围类对象的引用特权外, 与其他所冇内部类完全一样。在我们列举的示例中, 必须使用静态内部类,这是由于内部类对象是在静态方法中构造的

    注意:(1)在内部类不需要访问外围类对象的时候, 应该使用静态内部类。 有些程序员用嵌套类 (nested class ) 表示静态内部类

             ( 2)与常规内部类不同,静态内部类可以有静态域和方法。

          (3)声明在接口中的内部类自动成为 static 和 public 类

    第二部分:实验部分

    实验1 导入第6章示例程序,测试程序并进行代码注释。

    测试程序1:

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

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

    l 掌握接口的实现用法;

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

    代码如下:

    1>Employee类

    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
        */
       
       //重写接口的compare To方法
       public int compareTo(Employee other)
       {
          return Double.compare(salary, other.salary);
       }
    }

    2>EmployeeSortTest类

    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[0] = new Employee("Harry Hacker", 35000);
          staff[1] = new Employee("Carl Cracker", 75000);
          staff[2] = new Employee("Tony Tester", 38000);
    
          //使用mergesort算法对数组staff中的元素进行排序。要求数组中的元素必须实现了Comparable接口中的类,并且元素之间是可比较的。
          Arrays.sort(staff);
    
          //打印有关所有员工对象的信息
          for (Employee e : staff)
             System.out.println("name=" + e.getName() + ",salary=" + e.getSalary());
       }
    }

    运行结果如下:

    测试程序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);

      }

    }

    代码及注释如下:

    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引用了实现了接口A的类对象
           A a=new C( );
           //使用接口变量调用实现了接口A的类对象的方法
           a.show( );
           System.out.println("g="+C.g);
      }
    }

    运行结果如下:

    测试程序3:

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

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

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

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

    代码如下:

    
    

    /**
    @version 1.02 2017-12-14
    @author Cay Horstmann
    */

    
    

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import java.util.*;
    import javax.swing.Timer;

    
    

    public class TimerTest
    {
    public static void main(String[] args)
    {
    TimePrinter listener = new TimePrinter();

    
    

    // 构造一个调用listener的计时器
    // 每1秒一次
    Timer timer = new Timer(1000, 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 "
    + new Date());
    Toolkit.getDefaultToolkit().beep();
    }
    }

     

    运行结果如下:

    测试程序4:

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

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

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

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

    代码如下:

    1>Employee类

    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
       {
           //检查调用clone的对象的类有没有实现cloneable接口
           
           
          //调用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();
          
          // 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>CloneTest类

    /**
     * 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();
          copy.raiseSalary(10);
          copy.setHireDay(2002, 12, 31);
          System.out.println("original=" + original);
          System.out.println("copy=" + copy);
       }
    }

    运行结果如下:

    实验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" };  //定义数组plants;
          System.out.println(Arrays.toString(planets));
          System.out.println("Sorted in dictionary order:");
          Arrays.sort(planets);//Arrays.sort方法接受Lambda类的对象;
          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));//提供lanbda表达式在底层,Arrays.sort方法会接收实现Comparator<string>某各类的对象;
                 
          var 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?");   //保持程序运行,直到用户选择“OK"
          System.exit(0);        
       }
    }

    运行结果如下:

    注:以下实验课后完成

    实验3: 编程练习

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

    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.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:/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 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);
                    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;
        }
    }

    运行结果如下:

     实验总结:  本周测试中的lamdba表达式我有些没有理解清楚,在听了助教的讲解后,使我自己加深了它的理解。本次实验有很多的测试程序,在写代码注释的时候我更加着重的理解了它们的代码层次。尤其是本章的程序编写题目,虽然刚开始不会做,在读入文件时对于他的位置有些不懂,但在和同学交流之后我正确理解了它的意义。在今后的编程练习题中,我会更加努力,坚持自己写代码,早日提高自己的编程水平。

  • 相关阅读:
    python ModuleNotFoundError: No module named 'requests' 的 解决方案
    Win环境下如何在cmd运行python文件
    阿里云ECS服务器连接RDS数据库
    mysql5.6采集数据插入出现MySQL server has gone away解决办法
    Ubuntu 18.04 单系统U盘安装
    查看ubuntu系统是32位还是64位,查看系统版本
    Ubuntu 18.04 设置固定的静态ip
    Ubuntu 18.04 新系统 允许root远程登录设置方法
    ubuntu 新系统 使用root用户登录
    Ubuntu 18.04远程登录服务器--ssh的安装和配置
  • 原文地址:https://www.cnblogs.com/xiaobeike/p/11697582.html
Copyright © 2011-2022 走看看