实验七 接口的定义与使用

第一部分:理论知识

一、接口、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的用法。

-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[];
//用三个staff对象填充数组;
staff[] = new Employee("Harry Hacker", );
staff[] = new Employee("Carl Cracker", );
staff[] = new Employee("Tony Tester", ); Arrays.sort(staff);//按字母排序方法; // print out information about all Employee objects
for (Employee e : staff)
System.out.println("name=" + e.getName() + ",salary=" + e.getSalary());
}
}
例题 - 代码:
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;
}
//Name属性访问器;
public String getName()
{
return name;
}
//Salary属性访问器;
public double getSalary()
{
return salary;
}
//计算工资方法;
public void raiseSalary(double byPercent)
{
double raise = salary * byPercent / ;
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)//compareTo方法;
{
return Double.compare(salary, other.salary);//包装器,调用compare方法;
}
}

程序测试结果:

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

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

  - 代码:
package timer; /**
@version 1.02 2017-12-14
@author Cay Horstmann
*/ import java.awt.*;
import java.awt.event.*;
import java.time.*;
import javax.swing.*;
import javax.swing.Timer;
//用JavaUTIL计时器解决与java.util.Timer的矛盾 public class TimerTest
{
public static void main(String[] args)
{
ActionListener listener = new TimePrinter(); //构造一个调用侦听器的计时器;
//每十秒一次;
Timer t= new Timer(, listener);
t.start(); // keep program running until the user selects "OK"
JOptionPane.showMessageDialog(null, "Quit program?");
System.exit();
}
} class TimePrinter implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
System.out.println("At the tone, the time is "
+ Instant.ofEpochMilli(event.getWhen()));
Toolkit.getDefaultToolkit().beep();
}
}

程序6-3测试结果:

测试程序4:

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

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

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

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

- 代码:
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", );
original.setHireDay(, , );
Employee copy = original.clone();
copy.raiseSalary();
copy.setHireDay(, , );
System.out.println("original=" + original);
System.out.println("copy=" + copy);
}
}
- 代码:
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
{ Employee cloned = (Employee) super.clone();//返回Object对象后强制类型转换; // 克隆可变部分
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 - , day).getTime(); // 实例字段变异实例
hireDay.setTime(newHireDay.getTime());
} public void raiseSalary(double byPercent)
{
double raise = salary * byPercent / ;
salary += raise;
} public String toString()
{
return "Employee[name=" + name + ",salary=" + salary + ",hireDay=" + hireDay + "]";
}
}

程序测试结果:

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

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

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

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

6-6 代码:

  - 代码:
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)
{
//定义并初始化string类数组;
String[] planets = new String[] { "Mercury", "Venus", "Earth", "Mars",
"Jupiter", "Saturn", "Uranus", "Neptune" };
//排序前输出;
System.out.println(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:");
//按单词长度排序后,使用lambda表达式;
Arrays.sort(planets, (first, second) -> first.length() - second.length());
System.out.println(Arrays.toString(planets));
//方法引用;lambda表达式;
Timer t= new Timer(, event ->
System.out.println("The time is " + new Date()));
t.start(); // 继续运行程序,知道用户选择OK;
JOptionPane.showMessageDialog(null, "Quit program?");
System.exit();
}
}

程序测试结果:

Lambda表达式在C#中的写法是“arg-list => expr-body”,“=>”符号左边为表达式的参数列表,右边则是表达式体(body)。参数列表可以包含0到多个参数,参数之间使用逗号分割。Lambda表达式的作用也是为了定义一个匿名方法。如果Lambda表达式的body是一个表达式(expression),而不是语句(statement)的话,那么它的body就可以省略大括号和return关键字。此外,如果Lambda表达式只包含一个参数的话,则参数列表的括号也可以省略。

当然,Lambda表达式也并不是可以完全替代delegate写法,例如带ref和out关键字的匿名方法,就必须使用.NET 2.0中的delegate才能构造出来了。

实验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 main{
private static ArrayList<person> Personlist;
public static void main(String[] args) {
Personlist = 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 ID = linescanner.next();
String sex = linescanner.next();
String age = linescanner.next();
String place =linescanner.nextLine();
person Person = new person();
Person.setname(name);
Person.setID(ID);
Person.setsex(sex);
int a = Integer.parseInt(age);
Person.setage(a);
Person.setbirthplace(place);
Personlist.add(Person); }
} 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 :
Collections.sort(Personlist);
System.out.println(Personlist.toString());
break;
case : int max=,min=;int j,k1 = ,k2=;
for(int i=;i<Personlist.size();i++)
{
j=Personlist.get(i).getage();
if(j>max)
{
max=j;
k1=i;
}
if(j<min)
{
min=j;
k2=i;
} }
System.out.println("年龄最大:"+Personlist.get(k1));
System.out.println("年龄最小:"+Personlist.get(k2));
break;
case :
System.out.println("年龄:");
int yourage = scanner.nextInt();
int near=agenear(yourage);
int d=yourage-Personlist.get(near).getage();
System.out.println(""+Personlist.get(near));
break;
case :
System.out.println("你的家乡?");
String find = scanner.next();
String place=find.substring(,);
String place2=find.substring(,);
for (int i = ; i <Personlist.size(); i++)
{
if(Personlist.get(i).getbirthplace().substring(,).equals(place))
System.out.println(""+Personlist.get(i)); } break;
case :
isTrue = false;
System.out.println("退出程序!");
break;
default:
System.out.println("输入有误");
}
}
}
public static int agenear(int age) { int j=,min=,d=,k=;
for (int i = ; i < Personlist.size(); i++)
{
d=Personlist.get(i).getage()-age;
if(d<) d=-d;
if (d<min)
{
min=d;
k=i;
} } return k; } }
public class person implements Comparable<person> {
private String name;
private String ID;
private int age;
private String sex;
private String birthplace; public String getname() {
return name;
}
public void setname(String name) {
this.name = name;
}
public String getID() {
return ID;
}
public void setID(String ID) {
this.ID= ID;
}
public int getage() { return age;
}
public void setage(int age) {
// int a = Integer.parseInt(age);
this.age= age;
}
public String getsex() {
return sex;
}
public void setsex(String sex) {
this.sex= sex;
}
public String getbirthplace() {
return birthplace;
}
public void setbirthplace(String birthplace) {
this.birthplace= birthplace;
} public int compareTo(person o) {
return this.name.compareTo(o.getname()); } public String toString() {
return name+"\t"+sex+"\t"+age+"\t"+ID+"\t"+birthplace+"\n"; } }

程序测试结果:

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

实验程序1:

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

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

  - 代码:

package innerClass;

  import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.Timer; /**
10 * This program demonstrates the use of inner classes.
11 * @version 1.11 2015-05-12
12 * @author Cay Horstmann
13 */
public class InnerClassTest
{
public static void main(String[] args)
{
TalkingClock clock = new TalkingClock(, true);
clock.start(); // 保持程序运行知道用户选择OK;
JOptionPane.showMessageDialog(null, "Quit program?");
System.exit();
}
} /**
28 * A clock that prints the time in regular intervals.
29 */
class TalkingClock
{
private int interval;
private boolean beep; /**
36 * Constructs a talking clock
37 * @param interval the interval between messages (in milliseconds)
38 * @param beep true if the clock should beep
39 */
public TalkingClock(int interval, boolean beep)
{
this.interval = interval;
this.beep = beep;
} /**
47 * Starts the clock.
48 */
public void start()
{
ActionListener listener = new TimePrinter();
Timer t = new Timer(interval, listener);
t.start();
} public class TimePrinter implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
System.out.println("At the tone, the time is " + new Date());
if (beep) Toolkit.getDefaultToolkit().beep();
}
}
}

程序测试结果:

实验程序2:

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

l 掌握匿名内部类的用法。

  - 代码:
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.Timer; /**
8 * This program demonstrates anonymous inner classes.
9 * @version 1.11 2015-05-12
10 * @author Cay Horstmann
11 */
public class AnonymousInnerClassTest
{
public static void main(String[] args)
{
TalkingClock clock = new TalkingClock();
clock.start(, true); // 保持程序运行知道用户选择OK;
JOptionPane.showMessageDialog(null, "Quit program?");
System.exit();
}
} /**
26 * A clock that prints the time in regular intervals.
27 */
class TalkingClock
{
/**
31 * Starts the clock.
32 * @param interval the interval between messages (in milliseconds)
33 * @param beep true if the clock should beep
34 */
//匿名内部类;
public void start(int interval, boolean beep)
{
ActionListener listener = new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
System.out.println("At the tone, the time is " + new Date());
if (beep) Toolkit.getDefaultToolkit().beep();
}
};
Timer t = new Timer(interval, listener);
t.start();
}
}

程序测试结果:

实验程序3:

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

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

  - 代码:

package staticInnerClass;

  /**
4 * This program demonstrates the use of static inner classes.
5 * @version 1.02 2015-05-12
6 * @author Cay Horstmann
7 */
public class StaticInnerClassTest
{
public static void main(String[] args)
{
double[] d = new double[];
for (int i = ; i < d.length; i++)
d[i] = * Math.random();
ArrayAlg.Pair p = ArrayAlg.minmax(d);
System.out.println("min = " + p.getFirst());
System.out.println("max = " + p.getSecond());
}
} class ArrayAlg
{
/**
24 * A pair of floating-point numbers
25 */
public static class Pair
{
private double first;
private double second; /**
32 * Constructs a pair from two floating-point numbers
33 * @param f the first number
34 * @param s the second number
35 */
public Pair(double f, double s)
{
first = f;
second = s;
} /**
43 * Returns the first number of the pair
44 * @return the first number
45 */
public double getFirst()
{
return first;
} /**
52 * Returns the second number of the pair
53 * @return the second number
54 */
public double getSecond()
{
return second;
}
} /**
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 */
public static Pair minmax(double[] values)
{
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);
}
}

程序测试结果:

三、实验总结

本章主要学习了掌握接口定义方法;实现接口类的定义要求;实现了接口类的使用要求;程序回调设计模式;Comparator接口用法;对象浅层拷贝与深层拷贝方法;Lambda表达式语法;内部类的用途及语法要求。并知道了object类的clone方法,通过学长在群里的讲解明白了接口和继承之间的区别。在今后会更加努力。

201871010101-陈来弟《面向对象程序设计(Java)》第八周学习总结的更多相关文章

  1. 201771010134杨其菊《面向对象程序设计java》第九周学习总结

                                                                      第九周学习总结 第一部分:理论知识 异常.断言和调试.日志 1.捕获 ...

  2. 201871010132-张潇潇《面向对象程序设计(java)》第一周学习总结

    面向对象程序设计(Java) 博文正文开头 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cn ...

  3. 扎西平措 201571030332《面向对象程序设计 Java 》第一周学习总结

    <面向对象程序设计(java)>第一周学习总结 正文开头: 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 ...

  4. 杨其菊201771010134《面向对象程序设计Java》第二周学习总结

    第三章 Java基本程序设计结构 第一部分:(理论知识部分) 本章主要学习:基本内容:数据类型:变量:运算符:类型转换,字符串,输入输出,控制流程,大数值以及数组. 1.基本概念: 1)标识符:由字母 ...

  5. 201871010124 王生涛《面向对象程序设计JAVA》第一周学习总结

    项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://edu.cnblogs.com/campus/xbsf/ ...

  6. 201871010115——马北《面向对象程序设计JAVA》第二周学习总结

    项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...

  7. 201777010217-金云馨《面向对象程序设计(Java)》第二周学习总结

    项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...

  8. 201871010132——张潇潇《面向对象程序设计JAVA》第二周学习总结

    项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...

  9. 201771010123汪慧和《面向对象程序设计Java》第二周学习总结

    一.理论知识部分 1.标识符由字母.下划线.美元符号和数字组成, 且第一个符号不能为数字.标识符可用作: 类名.变量名.方法名.数组名.文件名等.第二部分:理论知识学习部分 2.关键字就是Java语言 ...

  10. 20155321 2016-2017-2 《Java程序设计》第八周学习总结

    20155321 2016-2017-2 <Java程序设计>第八周学习总结 教材学习内容总结 创建Logger对象 static Logger getLogger(String name ...

随机推荐

  1. python将xml文件数据增强(labelimg)

    在处理faster-rcnn和yolo时笔者使用labelimg标注图片 但是我们只截取了大概800张左右的图,这个量级在训练时肯定是不够的,所以我们需要使用数据增强(无非是旋转加噪调量度)来增加我们 ...

  2. jQuery中的事件对象(八)

    Event 对象代表事件的状态,比如事件在其中发生的元素.键盘按键的状态.鼠标的位置.鼠标按钮的状态. 一.事件对象基本认识 1. 什么时候会产生Event 对象呢?  例如: 当用户单击某个元素的时 ...

  3. 《Vue 进阶系列之响应式原理及实现》

    https://www.bilibili.com/video/av51444410/?p=5 https://github.com/amandakelake/blog/issues/63 https: ...

  4. Apache 监听 ipv4

    查看端口信息 ifconfig 发现只有 ipv6 的 80 端口被监听,ipv4 的 80 端口没有被监听 因此通过 ipv4 无法访问 tcp6 0 0 :::80 :::* LISTEN 221 ...

  5. 数论2&莫&杜

    积性函数: 积性函数定义ok 积性函数指对于所有互质的整数\(a\)和\(b\)有性质\(f(ab)=f(a)f(b)\)的数论函数 除数函数? 莫比乌斯函数\(\mu\)ok \[ \phi(i) ...

  6. 【2019.7.24 NOIP模拟赛 T1】道路建设(road)(水题)

    原题与此题 原题是一道神仙不可做题,两者区别在于,原题不能有重边和自环. 然而,这题可以有重边... 于是这题就变成了一道大水题. 此题的解法 考虑如何构造. 对于\(n\le10^4\)的情况: 对 ...

  7. 研究是一门艺术 (韦恩·C·布斯, 格雷戈里·G·卡洛姆, 约瑟夫·M·威廉姆斯 著)

    第一部分 研究,研究者与读者 前言: 开始一个研究计划 (已看) 第一章 以书面形式来思考 (已看) 第二章 与读者建立联系 第二部分 提问题,找答案 前言: 规划你的研究计划 第三章 从题目到问题 ...

  8. sessionStorage 、localStorage 、 cookie 和session之间的区别

    四者的异同 特性 Session   Cookie localStorage sessionStorage 数据的生命期   在一定时间内保存在服务器上.当访问增多,会比较占用你服务器的性能,考虑到减 ...

  9. AOP软件设计

    什么是面向方面的编程? 为什么面向方面的软件设计? 术语 关注 视口 关注点分离 人工制品 横切 方面 编织 零件 形式主义 第二节 案例研究 关注 人工制品 横切 方面 AspectJ 加入点 切入 ...

  10. ASP.NET Core 之 Identity 入门(转载)

    原文地址:https://www.cnblogs.com/gongap/p/9504562.html 前言 在 ASP.NET Core 中,仍然沿用了 ASP.NET里面的 Identity 组件库 ...