项目

内容

这个作业属于哪个课程

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: 编程练习

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

201871010102-常龙龙《面向对象程序设计(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. 20145236 《Java程序设计》第八周学习总结

    20145236 <Java程序设计>第八周学习总结 教材学习内容总结 第十四章 NIO与NIO2 认识NIO NIO使用频道(Channel)来衔接数据节点,在处理数据时,NIO可以让你 ...

随机推荐

  1. hadoop自带RPC的使用 代码demo

    引入的三方包 <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop- ...

  2. Paper | Predicting the Quality of Images Compressed After Distortion in Two Steps

    目录 1. 问题本质剖析 2. 方法细节 图像质量评估大佬AC Bovik的论文,发表在2019 TIP上. 考虑的问题:对于有参考图像质量评估(R-IQA)任务,参考图像有时是有损的.这会导致评估的 ...

  3. OpenCV Error: Unknown error code -10 (Raw image encoder error: Empty JPEG image (DNL not supported)) in throwOnEror 错误

    出现上面这样的错误可以肯定是传了空指针导致的, 刚开始出现这样的问题, 并且是概率性的, 网上找了一遍都没找到解决方案, 然后自己一行一行代码注释, 发现还是会出现这样的问题, 当时就懵逼了, 我从打 ...

  4. Jenkins安装第一个插件和通过离线安装包进行安装

    1.打开左侧Manage Jenkins 选择Manage Plugins菜单 2.搜索Folders插件,该插件用于创建一个目录 3.点击安装进入插件安装状态,Jenkins会自动下载相关联的插件 ...

  5. svn merge操作

    使用SVN做Merge操作时,会包含6个选项,下面就这6个选项给出详细的说明: 1.Merge a range of revisions 此类型应用最为广泛,主要是把源分支中的修改合并到目标分支上来. ...

  6. 【shell脚本】显示进度条

    使用动态时针版本显示进度条 [root@VM_0_10_centos shellScript]# cat progressBar.sh #!/bin/bash # 进度条,动态时针版本 # 定义显示进 ...

  7. C++:Copy & Reference Count

    浅拷贝.深拷贝 通常,我们会按如下方式书写拷贝构造函数: class LiF { public: LiF(int _lif = 0) : lif(_lif) {} // 默认构造函数 LiF(cons ...

  8. python asyncio call_soon, call_at, call_later

    1. call_soon, 协程一运行就马上运行 def callback(sleep_times): print("success time {}".format(sleep_t ...

  9. 短的 Guid 帮助类

    直接贴代码了: /// <summary> /// 短的 Guid 帮助类 /// </summary> public class ShortGuidHelper { #reg ...

  10. 微信小程序小Demo

    微信小程序小Demo 调用API,轮播图,排行榜,底部BabTar的使用... board // board/board.js Page({ /** * 页面的初始数据 */ // 可以是网络路径图片 ...