201871010131-张兴盼《面向对象程序设计(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) 了解内部类的用途及语法要求。 |
第一部分:总结第六章理论知识
6.1.1接口
1.Java为了克服单继承的缺点,Java使用了接口,一个类可以实现一个或多个接口。
2. 在Java程序设计语言中,接口不是类,而是对类的一组需求描述,由常量和一组抽象方法组成。
3. 接口中不包括变量和有具体实现的方法。
4.只要类实现了接口,则该类要遵从接口描述的统一格式进行定义,并且可以在任何需要该接口的地方使用这个类的对象.
5.声明方式: public interface 接口名 { …… } 接口体中包含常量定义和方法定义,接口中只进行方法的声明,不提供方法的实现。
6.类似建立类的继承关系,接口也可以扩展。 接口的扩展技术使得从具有较高通用性的接口存在多条链延伸到具有较高专用性的接口。
7.在类声明时用implements关键字声明使用一个或多个接口
class Employee implements Printable { …… }
一个类使用了某个接口,那么这个类必须实现该接口的所有方法,即为这些方法提供方法体。
一个类可以实现多个接口,接口间应该用逗号分隔开。
class Employee implements Cloneable,Comparable
8.接口不能构造接口对象,但可以声明接口变量以指向一个实现了该接口的类对象。
Comparablex = new Comparable(…); //ERROR
Comparable x= new Employee(…); //OK
9.可以用instanceof检查对象是否实现了某个接口。
if (anObject instanceof Comparable) { ……}
6.1.2 接口与抽象类
1.抽象类:用abstract来声明,没有具体实例对象的类,不能用new来创建对象。可包含常规类所包含的任何东西。抽象类必须由子类继承,如果abstract类的子类不是抽象类,那么子类必须重写父类中所有的abstract方法。
2.接口:用interfaces声明,是抽象方法和常量值定义的集合。从本质上讲,接口是一个特殊的抽象类,这种抽象类中只包含常量和方法的定义,而没有变量和方法的定义。接口中只能定义抽象方法,而且这些方法默认为public的。只有类实现了接口,就可以在任何需要该接口的地方使用这个类的对象。此外,一个类可以实现多个接口。
接口与抽象类的区别:
A.接口不能实现任何方法,而抽象类可以。
B.类可以实现许多接口,但只有一个父类。
C.接口不是类分级结构的一部分,无任何联系的类可以实现相同的接口。
6.2.1 接口实例
1.回调(callback):一种程序设计模式,在这种模式中,可指出某个特定事件发生时程序应该采取的动作。 在java.swing包中有一个Timer类,可以使用它在到达给定的时间间隔时触发一个事件。
2Compare接口
a)所在包:java.util.*
b)Comparator接口定义
public interface Comparator<T>{
int compare(T o1,T o2);
......
}
c)用途一:处理字符串按长度进行排序操作
3. Object类的Clone方法
a)当拷贝一个对象变量时,原始变量与拷贝变量引用同一个对象。这样,改变一个变量所引用的对象会对另一个变量产生影响。
b)如果要创建一个对象新的copy,它的最初状态与 original一样,但以后可以各自改变状态,就需要使用Object类的clone方法。
c)Object类的clone()方法是一个native方法。
d)Object类中的clone()方法被protected()修饰符修饰。这意味着在用户编写的代码中不能直接调用它。如果要直接应用clone()方法,就需覆盖clone()方法,并要把clone()方法的属性设置为public。
e)Object.clone()方法返回一个Object对象。必须进行强制类型转换才能得到所需要的类型。
4.浅层拷贝:被拷贝对象的所有常量成员和基本类型属性都有与原来对象相同的拷贝值,而若成员域是一个对象,则被拷贝对象该对象域的对象引用仍然指向原来的对象。
5.深层拷贝:被拷贝对象的所有成员域都含有与原 来对象相同的值,且对象域将指向被复制过的新对 象,而不是原有对象被引用的对象。换言之,深层拷贝将拷贝对象内引用的对象也拷贝一遍。
6.2.2 Java中对象克隆的实现
1.在子类中实现Cloneable接口
2.为了获得对象的一份拷贝,可以利用Object类的clone方法。
3.在子类中覆盖超类的clone方法,声明为public。
4.在子类的clone方法中,调用super.clone()。
6.3 Lambda表达式
1.Java Lambda表达式是Java 8引入的一个新的功能,主要用途是提供一个函数化的语法来简化编码。
2.Lambda表达式本质上是一个匿名方法。
public intadd(intx, inty) {
return x + y; }
转成Lambda表达式后是:
(intx, inty) -> x + y;
3.Lambda表达式的语法基本结构
(arguments)->body
有如下几种情况:
a)参数类型可推导时,不需要指定类型,如 (a)->System.out.println(a)
b)只有一个参数且类型可推导时,不强制写(),如 a->System.out.println(a)
c)参数指定类型时,必须有括号,如(int a)->System.out.println(a)
d)参数可以为空,如()->System.out.println("hello")
e)body需要用{}包含语句,当只有一条语句时{}可省略
4)函数式接口Functionallnterface
a)Java Lambda表达式以函数式接口为应用基础
b)函数式接口(Functionallnterface)
只有一个方法的接口,这类接口的目的是为了一个单一的操作。常见的接口如:ActionListener,Runnable,Comparator都是函数式接口,并且都
标注了注解@Functionallnterface.
c)函数式接口用作表示lambda表达式的类型。
6.4.1 内部类
1)内部类(inner class)是定义在一个类内部的类。
2)外层的类成为外部类(outer class).
3)内部类主要用于事件处理。 使用内部类的原因有以下三个:
a)内部类方法可以访问该类定义所在的作用域中的数据,包括私有数据。
b)内部类能够隐藏起来,不为同一包中的其他类所见。
c)想要定义一个回调函数且不想编写大量代码时, 使用匿名内部类比较便捷。
4)内部类的声明
内部类的声明格式如下:
[修饰符] class outerClass{
...
[修饰符]class innerClass{
...
}
...
}
5)内部类可以直接访问外部类的成员,包括private成员,但是内部类的成员却不能被外部类直接访问。内部类中加上修饰符访问外部类中的同名域。
6.4.2局部内部类
1)内部类并非只能在类内定义,也可以在程序块内定义局部内部类。例如,在方法中,甚至在for循环体内部。
2)局部内部类不能用public或private访问修饰符进行声明,它的作用域被限定在声明这个局部类的块中。
3)局部内部类可以访问方法中的final类型的局部变量。
6.4.3 匿名内部类
1)若只创建类的一个对象,则不该为该类命名,这种类称为匿名内部类。
2)由于匿名类没有类名,所以匿名类不能有构造器,取而代之的是将构造器参数传递给超类的构造器。
3)若匿名内部类实现接口时,则匿名内部类不能有任何构造参数。
4)如果构造参数的闭圆括号跟一个开花括号,表明正在定义的就是匿名内部类。
6.4.4 静态内部类
1)如果用static修饰一个内部类,这个类就相当于是一个外部定义的类,所以static的内部类中可以声明static成员,但非static的内部类中的成员不能声明为static的。
static的内部类不能再使用外部类的非static的成员变量。
2)static内部类很少使用。
第二部分:实验部分
实验1: 导入第6章示例程序,测试程序并进行代码注释。
测试程序1:编辑、编译、调试运行阅读教材214页-215页程序6-1、6-2,理解程序并分析程序运行结果;
在程序中相关代码处添加新知识的注释。
掌握接口的实现用法;
掌握内置接口Compareable的用法。
6-1代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
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 //EmployeeSortTest关联Employee; { public static void main(String[] args) { var 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);
Arrays.sort(staff); //进行排序;
// print out information about all Employee objects for (Employee e : staff) System.out.println("name=" + e.getName() + ",salary=" + e.getSalary()); } } |
运行结果如下:
项目 |
内容 |
这个作业属于哪个课程 |
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) 了解内部类的用途及语法要求。 |
第一部分:总结第六章理论知识
6.1.1接口
1.Java为了克服单继承的缺点,Java使用了接口,一个类可以实现一个或多个接口。
2. 在Java程序设计语言中,接口不是类,而是对类的一组需求描述,由常量和一组抽象方法组成。
3. 接口中不包括变量和有具体实现的方法。
4.只要类实现了接口,则该类要遵从接口描述的统一格式进行定义,并且可以在任何需要该接口的地方使用这个类的对象.
5.声明方式: public interface 接口名 { …… } 接口体中包含常量定义和方法定义,接口中只进行方法的声明,不提供方法的实现。
6.类似建立类的继承关系,接口也可以扩展。 接口的扩展技术使得从具有较高通用性的接口存在多条链延伸到具有较高专用性的接口。
7.在类声明时用implements关键字声明使用一个或多个接口
class Employee implements Printable { …… }
一个类使用了某个接口,那么这个类必须实现该接口的所有方法,即为这些方法提供方法体。
一个类可以实现多个接口,接口间应该用逗号分隔开。
class Employee implements Cloneable,Comparable
8.接口不能构造接口对象,但可以声明接口变量以指向一个实现了该接口的类对象。
Comparablex = new Comparable(…); //ERROR
Comparable x= new Employee(…); //OK
9.可以用instanceof检查对象是否实现了某个接口。
if (anObject instanceof Comparable) { ……}
6.1.2 接口与抽象类
1.抽象类:用abstract来声明,没有具体实例对象的类,不能用new来创建对象。可包含常规类所包含的任何东西。抽象类必须由子类继承,如果abstract类的子类不是抽象类,那么子类必须重写父类中所有的abstract方法。
2.接口:用interfaces声明,是抽象方法和常量值定义的集合。从本质上讲,接口是一个特殊的抽象类,这种抽象类中只包含常量和方法的定义,而没有变量和方法的定义。接口中只能定义抽象方法,而且这些方法默认为public的。只有类实现了接口,就可以在任何需要该接口的地方使用这个类的对象。此外,一个类可以实现多个接口。
接口与抽象类的区别:
A.接口不能实现任何方法,而抽象类可以。
B.类可以实现许多接口,但只有一个父类。
C.接口不是类分级结构的一部分,无任何联系的类可以实现相同的接口。
6.2.1 接口实例
1.回调(callback):一种程序设计模式,在这种模式中,可指出某个特定事件发生时程序应该采取的动作。 在java.swing包中有一个Timer类,可以使用它在到达给定的时间间隔时触发一个事件。
2Compare接口
a)所在包:java.util.*
b)Comparator接口定义
public interface Comparator<T>{
int compare(T o1,T o2);
......
}
c)用途一:处理字符串按长度进行排序操作
3. Object类的Clone方法
a)当拷贝一个对象变量时,原始变量与拷贝变量引用同一个对象。这样,改变一个变量所引用的对象会对另一个变量产生影响。
b)如果要创建一个对象新的copy,它的最初状态与 original一样,但以后可以各自改变状态,就需要使用Object类的clone方法。
c)Object类的clone()方法是一个native方法。
d)Object类中的clone()方法被protected()修饰符修饰。这意味着在用户编写的代码中不能直接调用它。如果要直接应用clone()方法,就需覆盖clone()方法,并要把clone()方法的属性设置为public。
e)Object.clone()方法返回一个Object对象。必须进行强制类型转换才能得到所需要的类型。
4.浅层拷贝:被拷贝对象的所有常量成员和基本类型属性都有与原来对象相同的拷贝值,而若成员域是一个对象,则被拷贝对象该对象域的对象引用仍然指向原来的对象。
5.深层拷贝:被拷贝对象的所有成员域都含有与原 来对象相同的值,且对象域将指向被复制过的新对 象,而不是原有对象被引用的对象。换言之,深层拷贝将拷贝对象内引用的对象也拷贝一遍。
6.2.2 Java中对象克隆的实现
1.在子类中实现Cloneable接口
2.为了获得对象的一份拷贝,可以利用Object类的clone方法。
3.在子类中覆盖超类的clone方法,声明为public。
4.在子类的clone方法中,调用super.clone()。
6.3 Lambda表达式
1.Java Lambda表达式是Java 8引入的一个新的功能,主要用途是提供一个函数化的语法来简化编码。
2.Lambda表达式本质上是一个匿名方法。
public intadd(intx, inty) {
return x + y; }
转成Lambda表达式后是:
(intx, inty) -> x + y;
3.Lambda表达式的语法基本结构
(arguments)->body
有如下几种情况:
a)参数类型可推导时,不需要指定类型,如 (a)->System.out.println(a)
b)只有一个参数且类型可推导时,不强制写(),如 a->System.out.println(a)
c)参数指定类型时,必须有括号,如(int a)->System.out.println(a)
d)参数可以为空,如()->System.out.println("hello")
e)body需要用{}包含语句,当只有一条语句时{}可省略
4)函数式接口Functionallnterface
a)Java Lambda表达式以函数式接口为应用基础
b)函数式接口(Functionallnterface)
只有一个方法的接口,这类接口的目的是为了一个单一的操作。常见的接口如:ActionListener,Runnable,Comparator都是函数式接口,并且都
标注了注解@Functionallnterface.
c)函数式接口用作表示lambda表达式的类型。
6.4.1 内部类
1)内部类(inner class)是定义在一个类内部的类。
2)外层的类成为外部类(outer class).
3)内部类主要用于事件处理。 使用内部类的原因有以下三个:
a)内部类方法可以访问该类定义所在的作用域中的数据,包括私有数据。
b)内部类能够隐藏起来,不为同一包中的其他类所见。
c)想要定义一个回调函数且不想编写大量代码时, 使用匿名内部类比较便捷。
4)内部类的声明
内部类的声明格式如下:
[修饰符] class outerClass{
...
[修饰符]class innerClass{
...
}
...
}
5)内部类可以直接访问外部类的成员,包括private成员,但是内部类的成员却不能被外部类直接访问。内部类中加上修饰符访问外部类中的同名域。
6.4.2局部内部类
1)内部类并非只能在类内定义,也可以在程序块内定义局部内部类。例如,在方法中,甚至在for循环体内部。
2)局部内部类不能用public或private访问修饰符进行声明,它的作用域被限定在声明这个局部类的块中。
3)局部内部类可以访问方法中的final类型的局部变量。
6.4.3 匿名内部类
1)若只创建类的一个对象,则不该为该类命名,这种类称为匿名内部类。
2)由于匿名类没有类名,所以匿名类不能有构造器,取而代之的是将构造器参数传递给超类的构造器。
3)若匿名内部类实现接口时,则匿名内部类不能有任何构造参数。
4)如果构造参数的闭圆括号跟一个开花括号,表明正在定义的就是匿名内部类。
6.4.4 静态内部类
1)如果用static修饰一个内部类,这个类就相当于是一个外部定义的类,所以static的内部类中可以声明static成员,但非static的内部类中的成员不能声明为static的。
static的内部类不能再使用外部类的非static的成员变量。
2)static内部类很少使用。
第二部分:实验部分
实验1: 导入第6章示例程序,测试程序并进行代码注释。
测试程序1:编辑、编译、调试运行阅读教材214页-215页程序6-1、6-2,理解程序并分析程序运行结果;
在程序中相关代码处添加新知识的注释。
掌握接口的实现用法;
掌握内置接口Compareable的用法。
6-1代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
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 //EmployeeSortTest关联Employee; { public static void main(String[] args) { var 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);
Arrays.sort(staff); //进行排序;
// print out information about all Employee objects for (Employee e : staff) System.out.println("name=" + e.getName() + ",salary=" + e.getSalary()); } } |
运行结果如下:
6-2代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
package interfaces;
public class Employee implements Comparable<Employee>//Employee实现JDK内置接口Comparable { 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);//静态Double.compare方法 } } |
运行结果如下:
测试程序二:编辑、编译、调试以下程序,结合程序运行结果理解程序;
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
package test; interface A { double g=9.8; void show( ); } class C implements A { public void show( ) {System.out.println("g="+g);} }
public class InterfaceTest { public static void main(String[ ] args) { A a=new C( ); a.show( ); System.out.println("g="+C.g); } } |
运行结果如下:
测试程序三:
在elipse IDE中调试运行教材223页6-3,结合程序运行结果理解程序;
26行、36行代码参阅224页,详细内容涉及教材12章。
在程序中相关代码处添加新知识的注释。
掌握回调程序设计模式;
6-3代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
package timer;
/** @version 1.02 2017-12-14 @author Cay Horstmann */
import java.awt.*; import java.awt.event.*; import java.time.*; import javax.swing.*;
public class TimerTest { public static void main(String[] args) { var listener = new TimePrinter(); //创建类对象;
// construct a timer that calls the listener // once every second //时间间隔为10秒; var timer = new Timer(1000, listener); //创建Timer类对象; timer.start();
// keep program running until the user selects "OK" //显示一个包含一条消息和OK按钮的对话框; JOptionPane.showMessageDialog(null, "Quit program?"); //parent为null时对话框显示在屏幕的中央; System.exit(0); } }
class TimePrinter implements ActionListener //接口定义在implement包中; { public void actionPerformed(ActionEvent event)//入口参数为ActionEvent event; { System.out.println("At the tone, the time is " + Instant.ofEpochMilli(event.getWhen())); Toolkit.getDefaultToolkit().beep(); //工具箱包含有关GUI环境的信息; } } |
运行结果如下:
测试程序4
调试运行教材229页-231页程序6-4、6-5,结合程序运行结果理解程序;
在程序中相关代码处添加新知识的注释.
掌握对象克隆实现技术;
掌握浅拷贝和深拷贝的差别。
6-4代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
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 { var original = new Employee("John Q. Public", 50000); original.setHireDay(2000, 1, 1); Employee copy = original.clone(); //新对象copy初始状态与original相同,之后会有各自不同的状态; copy.raiseSalary(10); copy.setHireDay(2002, 12, 31); System.out.println("original=" + original); System.out.println("copy=" + copy); } } |
运行结果如下:
6-5代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
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 //重新定义clone为public,创建深拷贝的clone的方法; { // call Object.clone() // 创建深拷贝的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: 导入第6章示例程序6-6,学习Lambda表达式用法。
调试运行教材233页-234页程序6-6,结合程序运行结果理解程序;
在程序中相关代码处添加新知识的注释。
将27-29行代码与教材223页程序对比,将27-29行代码与此程序对比,体会Lambda表达式的优点。
6-6代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
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 查询人员中是否有你的同乡。
实验代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
package ID;
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; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
package ID; public class Citizen implements Comparable<Citizen> {
private String name; private String id; private String sex; private int age; 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 String getSex() { return sex; }
public void setSex(String sex) { this.sex = sex; }
public int getage() { return age; }
public void setage(int age) { this.age = age; }
public String getBirthplace() { return birthplace; }
public void setBirthplace(String birthplace) { this.birthplace = birthplace; }
public int compareTo(Citizen other) { return this.name.compareTo(other.getName()); }
public String toString() { return name + "\t" + sex + "\t" + age + "\t" + id + "\t" + birthplace + "\n"; } } |
运行结果如下:
实验4:内部类语法验证实验
实验程序1:
编辑、调试运行教材246页-247页程序6-7,结合程序运行结果理解程序;
了解内部类的基本用法。
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
import java.awt.*; import java.awt.event.*; import java.util.*; import javax.swing.*; import javax.swing.Timer;
/** * This program demonstrates the use of inner classes. * @version 1.11 2015-05-12 * @author Cay Horstmann */ public class InnerClassTest { public static void main(String[] args) { TalkingClock clock = new TalkingClock(1000, true); clock.start();
// keep program running until user selects "Ok" JOptionPane.showMessageDialog(null, "Quit program?"); System.exit(0); } }
/** * A clock that prints the time in regular intervals. */ class TalkingClock { private int interval; private boolean beep;
/** * Constructs a talking clock * @param interval the interval between messages (in milliseconds) * @param beep true if the clock should beep */ public TalkingClock(int interval, boolean beep) { this.interval = interval; this.beep = beep; }
/** * Starts the clock. */ 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(interval)); if (beep) Toolkit.getDefaultToolkit().beep(); } } } |
运行结果如下:
实验程序2:
l 编辑、调试运行教材254页程序6-8,结合程序运行结果理解程序;
l 掌握匿名内部类的用法。
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
import java.awt.*; import java.awt.event.*; import java.util.*; import javax.swing.*; import javax.swing.Timer;
/** * This program demonstrates anonymous inner classes. * @version 1.11 2015-05-12 * @author Cay Horstmann */ public class AnonymousInnerClassTest { public static void main(String[] args) { TalkingClock clock = new TalkingClock(); clock.start(1000, true);
// keep program running until user selects "Ok" JOptionPane.showMessageDialog(null, "Quit program?"); System.exit(0); } }
/** * A clock that prints the time in regular intervals. */ class TalkingClock { /** * Starts the clock. * @param interval the interval between messages (in milliseconds) * @param beep true if the clock should beep */ 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,结合程序运行结果理解程序;
了解静态内部类的用法。
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
/** * This program demonstrates the use of static inner classes. * @version 1.02 2015-05-12 * @author Cay Horstmann */ public class StaticInnerClassTest { public static void main(String[] args) { var values = new double[20]; for (int i = 0; i < values.length; i++) values[i] = 100 * Math.random(); ArrayAlg.Pair p = ArrayAlg.minmax(values); System.out.println("min = " + p.getFirst()); System.out.println("max = " + p.getSecond()); } }
class ArrayAlg { /** * A pair of floating-point numbers */ public static class Pair { private double first; private double second;
/** * Constructs a pair from two floating-point numbers * @param f the first number * @param s the second number */ public Pair(double f, double s) { first = f; second = s; }
/** * Returns the first number of the pair * @return the first number */ public double getFirst() { return first; }
/** * Returns the second number of the pair * @return the second number */ public double getSecond() { return second; } }
/** * Computes both the minimum and the maximum of an array * @param values an array of floating-point numbers * @return a pair whose first element is the minimum and whose second element * is the maximum */ 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); } } |
运行结果如下:
三、实验总结
本周的学习过程中,主要了解了接口,接口和继承在某些方面比较相似,但是接口又在继承的基础上发展了一些优点,克服了java单继承的缺点。在学习过程中,可能是因为接口并不是具体的类,它只是实现,所以感觉接口比继承抽象一些,不太容易理解。但通过这周的学习以及实验中对具体程序的运行,对接口有了一定的掌握。自己编写饰演的过程中,在之前的基础上有的接口等新内容,自己还是不能独立完成,在同学的帮助下才勉强完成了实验。在实验课上老师讲的克隆以及函数接口等,自己还没有太掌握,在之后的学习中,一定会继续深入学习。