关键词:
1、实验目的与要求
(1) 理解泛型概念;
(2) 掌握泛型类的定义与使用;
(3) 掌握泛型方法的声明与使用;
(4) 掌握泛型接口的定义与实现;
(5)了解泛型程序设计,理解其用途。
一、理论知识
泛型类的定义:
(1)泛型:也称参数化类型(parameterized type),就是在定义类、接口和方法时,通过类型参数指示将要处理的对象型。
(2)一个泛型类(generic class)就是具有一个或多个类型变量的类,即创建用类型作为参数的类。
如一个泛型类定义格式如下:class Generics<K,V>
(3)Pair类引入了一个类型变量T,用尖括号(<>)括起来,并放在类名的后面。
泛型变量的限定:
(1)extends关键字所声明的上界既可以是一个类,也可以是一个接口;
(2)<T extends Bounding Type>表示T应该是绑定类型的子类型。
泛型变量下界的说明:
– 通过使用super关键字可以固定泛型参数的类型为某种
类型或者其超类
– 当程序希望为一个方法的参数限定类型时,通常可以使
用下限通配符
泛型类的约束与局限性:
不能用基本类型实例化类型参数
运行时类型查询只适用于原始类型
不能抛出也不能捕获泛型类实例
参数化类型的数组不合法不能实例化类型变量
泛型类的静态上下文中类型变量无效
注意擦除后的冲突
通配符类型:
“?”符号表明参数的类型可以是任何一种类型,它和参数T的含义是有区别的。T表示一种未知类型,而“?”表示任何一种类型.
这种通配符一般有以下三种用法:
单独的?,用于表示任何类型。
? extends type,表示带有上界。
? super type,表示带有下界。
二、实验内容和步骤
实验1: 导入第8章示例程序,测试程序并进行代码注释。
测试程序1:
l 编辑、调试、运行教材311、312页 代码,结合程序运行结果理解程序;
l 在泛型类定义及使用代码处添加注释;
l 掌握泛型类的定义及使用.
package pair1; /** * @version 1.00 2004-05-10 * @author Cay Horstmann */ public class Pair<T>//Pair类引入了一个类型变量T private T first;//use the type variable private T second; public Pair() first = null; second = null; public Pair(T first, T second) this.first = first; this.second = second; //构造方法的调用 public T getFirst() return first; //返回值 public T getSecond() return second; public void setFirst(T newValue) first = newValue; //入口参数 public void setSecond(T newValue) second = newValue;
package pair1; /** * @version 1.01 2012-01-26 * @author Cay Horstmann */ public class PairTest1 public static void main(String[] args) String[] words = "Mary", "had", "a", "little", "lamb" ;//定义常量 Pair<String> mm = ArrayAlg.minmax(words);//类名调用方法名 System.out.println("min = " + mm.getFirst()); System.out.println("max = " + mm.getSecond());//输出最大值、最小值 class ArrayAlg /** * Gets the minimum and maximum of an array of strings. * @param a an array of strings * @return a pair with the min and max value, or null if a is null or empty */ public static Pair<String> minmax(String[] a)//泛型类实例化 if (a == null || a.length == 0) return null; String min = a[0]; String max = a[0]; for (int i = 1; i < a.length; i++) if (min.compareTo(a[i]) > 0) min = a[i];//compareTo比较方法 if (max.compareTo(a[i]) < 0) max = a[i]; return new Pair<>(min, max);//实例化后的调用对象
结果如下:
测试程序2:
l 编辑、调试运行教材315页 PairTest2,结合程序运行结果理解程序;
l 在泛型程序设计代码处添加相关注释;
掌握泛型方法、泛型变量限定的定义及用途。
package pair1; /** * @version 1.00 2004-05-10 * @author Cay Horstmann */ public class Pair<T>//Pair类引入了一个类型变量T private T first;//use the type variable private T second; public Pair() first = null; second = null; public Pair(T first, T second) this.first = first; this.second = second; //构造方法的调用 public T getFirst() return first; //返回值 public T getSecond() return second; public void setFirst(T newValue) first = newValue; //入口参数 public void setSecond(T newValue) second = newValue;
package pair2; import java.time.*; /** * @version 1.02 2015-06-21 * @author Cay Horstmann */ public class PairTest2 public static void main(String[] args) LocalDate[] birthdays = LocalDate.of(1906, 12, 9), // G. Hopper LocalDate.of(1815, 12, 10), // A. Lovelace LocalDate.of(1903, 12, 3), // J. von Neumann LocalDate.of(1910, 6, 22), // K. Zuse ; Pair<LocalDate> mm = ArrayAlg.minmax(birthdays);//实例化一个LocalDat类 System.out.println("min = " + mm.getFirst()); System.out.println("max = " + mm.getSecond());//得到min、max class ArrayAlg /** Gets the minimum and maximum of an array of objects of type T. @param a an array of objects of type T @return a pair with the min and max value, or null if a is null or empty */ public static <T extends Comparable> Pair<T> minmax(T[] a) //将T限制为实现Comparable接口的类 if (a == null || a.length == 0) return null; T min = a[0]; T max = a[0]; for (int i = 1; i < a.length; i++)//compareTo方法 if (min.compareTo(a[i]) > 0) min = a[i]; if (max.compareTo(a[i]) < 0) max = a[i]; return new Pair<>(min, max);//返回新的pair类
结果如下:
测试程序3:
用调试运行教材335页 PairTest3,结合程序运行结果理解程序;
了解通配符类型的定义及用途。
package pair3; /** * @version 1.01 2012-01-26 * @author Cay Horstmann */ public class PairTest3 public static void main(String[] args) //定义Manager类 Manager ceo = new Manager("Gus Greedy", 800000, 2003, 12, 15); Manager cfo = new Manager("Sid Sneaky", 600000, 2003, 12, 15); Pair<Manager> buddies = new Pair<>(ceo, cfo); printBuddies(buddies); ceo.setBonus(1000000); cfo.setBonus(500000); Manager[] managers = ceo, cfo ; Pair<Employee> result = new Pair<>();//程序调用泛型方法 minmaxBonus(managers, result);//泛型方法 System.out.println("first: " + result.getFirst().getName() + ", second: " + result.getSecond().getName()); maxminBonus(managers, result); System.out.println("first: " + result.getFirst().getName() + ", second: " + result.getSecond().getName()); public static void printBuddies(Pair<? extends Employee> p) Employee first = p.getFirst(); Employee second = p.getSecond(); System.out.println(first.getName() + " and " + second.getName() + " are buddies."); public static void minmaxBonus(Manager[] a, Pair<? super Manager> result) //任何泛型Pair类型,它的类型参数是Manager的子类 if (a.length == 0) return; Manager min = a[0]; Manager max = a[0]; for (int i = 1; i < a.length; i++) if (min.getBonus() > a[i].getBonus()) min = a[i]; if (max.getBonus() < a[i].getBonus()) max = a[i]; result.setFirst(min); result.setSecond(max); public static void maxminBonus(Manager[] a, Pair<? super Manager> result)//统配符限制为Manager的所有超类型 minmaxBonus(a, result); PairAlg.swapHelper(result); // OK--swapHelper captures wildcard type // Can‘t write public static <T super manager> ... class PairAlg public static boolean hasNulls(Pair<?> p)//泛型类;类型变量的通配符“?” return p.getFirst() == null || p.getSecond() == null; public static void swap(Pair<?> p) swapHelper(p); //swap调用swapHelper public static <T> void swapHelper(Pair<T> p) T t = p.getFirst(); p.setFirst(p.getSecond()); p.setSecond(t);
Employee:
package pair3; import java.time.*; public class Employee //构造一个Employee类 private String name; private double salary; private LocalDate hireDay; public Employee(String name, double salary, int year, int month, int day) this.name = name;//this直接引用 this.salary = salary; hireDay = LocalDate.of(year, month, day); //访问器方法 public String getName() return name; public double getSalary() return salary; public LocalDate getHireDay() return hireDay; public void raiseSalary(double byPercent) double raise = salary * byPercent / 100; salary += raise;
Manager:
package pair3; public class Manager extends Employee//Manager类的父类是Employee类 private double bonus; /** @param name the employee‘s name @param salary the salary @param year the hire year @param month the hire month @param day the hire day */ public Manager(String name, double salary, int year, int month, int day) super(name, salary, year, month, day); bonus = 0; public double getSalary() double baseSalary = super.getSalary(); return baseSalary + bonus; public void setBonus(double b) bonus = b; public double getBonus() return bonus; l
结果如下:
实验2:编程练习:
编程练习1:实验九编程题总结
- 实验九编程练习1总结(从程序总体结构说明、模块说明,目前程序设计存在的困难与问题三个方面阐述)。
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.Collections; import java.util.Scanner; @SuppressWarnings("unused") public class Main private static ArrayList<Person> Personlist; @SuppressWarnings("resource") public static void main(String[] args) Personlist = new ArrayList<>(); Scanner scanner = new Scanner(System.in); File file = new File("E:\\新建文件夹\\身份证号.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("————————————————————————————————————————"); System.out.println("1:按姓名字典序输出人员信息"); System.out.println("2:查询最大年龄人员信息和最小年龄人员信息"); System.out.println("3:输入你的年龄,查询年龄与你最近人的所有信息"); System.out.println("4:查询人员中是否有你的同乡"); int nextInt = scanner.nextInt(); switch (nextInt) case 1: Collections.sort(Personlist); System.out.println(Personlist.toString()); break; case 2: int max=0,min=100;int j,k1 = 0,k2=0; for(int i=1;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 3: System.out.println("place?"); String find = scanner.next(); String place=find.substring(0,3); String place2=find.substring(0,3); for (int i = 0; i <Personlist.size(); i++) if(Personlist.get(i).getbirthplace().substring(1,4).equals(place)) System.out.println(""+Personlist.get(i)); break; case 4: System.out.println("年龄:"); int yourage = scanner.nextInt(); int near=agenear(yourage); int d_value=yourage-Personlist.get(near).getage(); System.out.println(""+Personlist.get(near)); /* for (int i = 0; i < Personlist.size(); i++) int p=Personlist.get(i).getage()-yourage; if(p<0) p=-p; if(p==d_value) System.out.println(Personlist.get(i)); */ break; case 5: isTrue = false; System.out.println("退出程序!"); break; default: System.out.println("输入有误"); public static int agenear(int age) int j=0,min=53,d_value=0,k=0; for (int i = 0; i < Personlist.size(); i++) d_value=Personlist.get(i).getage()-age; if(d_value<0) d_value=-d_value; if (d_value<min) min=d_value; k=i; return k;
程序总体结构:总体分为Main类和Person类
Main类:
1、将人员身份信息导入代码中
2、编辑了查找人员信息的方法
3、分5个case来分别说年龄大小、同乡等消息
Person类:
package ID; 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+" "+sex+" "+age+" "+ID+" "+birthplace+" ";
对各个小模块进行具体的分析
程序设计存在的困难与问题:
1、编写时基础错误还是很多
2、Main类和Person类的变量名有时不能统一
- 实验九编程练习2总结(从程序总体结构说明、模块说明,目前程序设计存在的困难与问题三个方面阐述)。
程序总体结构:Demo主类和Counter类
模块说明:Demo主类
import java.io.FileNotFoundException; import java.io.PrintWriter; import java.util.Scanner; public class Demo public static void main(String[] args) Scanner in = new Scanner(System.in); jf counter=new jf(); PrintWriter out = null; try out = new PrintWriter("text.txt"); catch (FileNotFoundException e) // TODO Auto-generated catch block e.printStackTrace(); int sum = 0; for (int i = 1; i <=10; i++) int a = (int) Math.round(Math.random() * 100); int b = (int) Math.round(Math.random() * 100); int m= (int) Math.round(Math.random() * 3); switch(m) case 0: System.out.println(i+": "+a+"/"+b+"="); while(b==0) b = (int) Math.round(Math.random() * 100); int c0 = in.nextInt(); out.println(a+"/"+b+"="+c0); if (c0 == jf.division(a, b)) sum += 10; System.out.println("恭喜答案正确"); else System.out.println("抱歉,答案错误"); break; case 1: System.out.println(i+": "+a+"*"+b+"="); int c = in.nextInt(); out.println(a+"*"+b+"="+c); if (c == counter.multiplication(a, b)) sum += 10; System.out.println("恭喜答案正确"); else System.out.println("抱歉,答案错误"); break; case 2: System.out.println(i+": "+a+"+"+b+"="); int c1 = in.nextInt(); out.println(a+"+"+b+"="+c1); if (c1 == counter.add(a, b)) sum += 10; System.out.println("恭喜答案正确"); else System.out.println("抱歉,答案错误"); break ; case 3: System.out.println(i+": "+a+"-"+b+"="); int c2 = in.nextInt(); out.println(a+"-"+b+"="+c2); if (c2 == counter.reduce(a, b)) sum += 10; System.out.println("恭喜答案正确"); else System.out.println("抱歉,答案错误"); break ; System.out.println("成绩"+sum); out.println("成绩:"+sum); out.close();
1、判断答案的正确性代码
2、文件的读取
3、四则运算代码的具体呈现
Counter类
public class Counter private int a; private int b; public int add(int a,int b) return a+b; public int reduce(int a,int b) return a-b; public int multiplication(int a,int b) return a*b; public int division(int a,int b) if(b!=0) return a/b; else return 0;
四则运算的计算过程及返回值
程序设计存在的困难与问题:
1、数值过大,无法口算
2、运算复杂,不符合基础运算难度
编程练习2:采用泛型程序设计技术改进实验九编程练习2,使之可处理实数四则运算,其他要求不变。
package C; import java.io.FileNotFoundException; import java.io.PrintWriter; import java.util.Random; import java.util.Scanner; public class Main public static void main(String[] args) Scanner in = new Scanner(System.in); Suanfa counter = new Suanfa(); PrintWriter out = null; try out = new PrintWriter("test.txt"); catch (FileNotFoundException e) System.out.println("文件夹输出失败"); e.printStackTrace(); int sum = 0; for (int i = 1; i <= 10; i++) int a = (int) Math.round(Math.random() * 100); int b = (int) Math.round(Math.random() * 100); int m; Random rand = new Random(); m = (int) rand.nextInt(4) + 1; System.out.println("随机生成的四则运算类型:" + m); switch (m) case 1: a = b + (int) Math.round(Math.random() * 100); while(b == 0) b = (int) Math.round(Math.random() * 100); while(a % b != 0) a = (int) Math.round(Math.random() * 100); //若生成的除法式子必须能整除,且满足分母为0的条件,则a一定要大于b,且a模b的结果要为0。 System.out.println(i + ": " + a + "/" + b + "="); int c0 = in.nextInt(); out.println(a + "/" + b + "=" + c0); if (c0 == counter.d(a, b)) sum += 10; System.out.println("正确!"); else System.out.println("错误!"); break; case 2: System.out.println(i + ": " + a + "*" + b + "="); int c = in.nextInt(); out.println(a + "*" + b + "=" + c); if (c == counter.m(a, b)) sum+= 10; System.out.println("正确!"); else System.out.println("错误!"); break; case 3: System.out.println(i + ": " + a + "+" + b + "="); int c1 = in.nextInt(); out.println(a + "+" + b + "=" + c1); if (c1 == counter.add(a, b)) sum += 10; System.out.println("正确!"); else System.out.println("错误!"); break; case 4: while (a < b) b = (int) Math.round(Math.random() * 100); //因为不能产生运算结果为负数的减法式子,所以a一定要大于b。若a<b,则重新生成b。 System.out.println(i + ": " + a + "-" + b + "="); int c2 = in.nextInt(); out.println(a + "-" + b + "=" + c2); if (c2 == counter.r(a, b)) sum += 10; System.out.println("正确!"); else System.out.println("错误!"); break; System.out.println("成绩" + sum); out.println("成绩:" + sum); out.close();
package C; public class Suanfa<T> private T a; private T b; public int add(int a,int b) return a + b; public int r(int a, int b) return a - b; public int m(int a, int b) return a * b; public int d(int a, int b) if (b != 0 && a%b==0) return a / b; else return 0;
结果如下:
三、总结如下:
本章我们学习了泛型程序设计技术,首先理解了泛型概念,掌握泛型类的定义与使用,泛型方法的声明与使用,最后感觉了解泛型程序设计及其用途,在验证实验中,通过对代码的解读,更深的学习了泛型程序<T>的使用,还复习了实验九的两个编程题目,感觉依旧存在些小问题,在接下来的实验中要更好的解决,编程实验中,在实验九的四则运算基础上,加入了本章泛型程序的概念,虽然不是很熟练,但还是勉强做出来了。
201771010135杨蓉庆《面对对象程序设计(java)》第九周学习总结(代码片段)
第7章异常、日志、断言和调试1、实验目的与要求(1)掌握java异常处理技术;(2)了解断言的用法;(3)了解日志的用途;(4)掌握程序基础调试技巧;一、理论知识1、异常:在程序的执行过程中所发生的异常事件,它中断指令的正常执... 查看详情
201771010135杨蓉庆《面对对象程序设计(java)》第七周学习总结(代码片段)
学习目标1、深入理解OO程序设计的特征:继承、多态;2、熟练掌握Java语言中基于类、继承技术构造程序的语法知识;3、利用继承定义类设计程序,能够设计开发含有1个主类、2个以上用户自定义类的应用程序。1、实验目的与要... 查看详情
201771010135杨蓉庆《面对对象程序设计(java)》第十八周学习总结(代码片段)
1、实验目的与要求(1) 综合掌握java基本程序结构; (2) 综合掌握java面向对象程序设计特点;(3) 综合掌握java GUI 程序设计结构;(4) 综合掌握java多线程编程模型;(5) 综合编程练习。 2、实验内容和... 查看详情
杨蓉庆201771010135《面向对象程序设计(java)》第一周学习总结
第一部分:课程准备部分填写课程学习平台注册账号,平台名称注册账号博客园:www.cnblogs.com艾特大家程序设计评测:https://pintia.cn/艾特你代码托管平台:https://github.com/艾特你@m中国大学MOOC: https://www.icourse163.org/1063769427以下... 查看详情
201771010135杨蓉庆《面向对象程序设计(java)》第四周学习总结(代码片段)
学习目标1、掌握类与对象的基础概念,理解类与对象的关系;2、掌握对象与对象变量的关系;3、掌握预定义类的基本使用方法,熟悉Math类、String类、math类、Scanner类、LocalDate类的常用API;4、掌握用户自定义类的语法规则,包... 查看详情
201771010135杨蓉庆《面向对象程序设计(java)》第二周学习总结
第一部分:理论知识学习部分3.1标识符:由字母、下划线、美元符号和数字组成,且第一个符号不能为数字,可用作:类名、变量名、方法名、数组名、文件名等。有Hello、$1234、程序名、www_123等。(2)关键词:是java语言中已经被... 查看详情
201771010135杨蓉庆《面对对象程序设计(java)》第十六周学习总结(代码片段)
1、实验目的与要求(1) 掌握线程概念;(2) 掌握线程创建的两种技术;(3) 理解和掌握线程的优先级属性及调度方法;(4) 掌握线程同步的概念及实现技术;一、理论知识?线程的概念 (1)多线程是进程执行过程中... 查看详情
201771010135杨蓉庆《面向对象程序设计(java)》第六周学习总结(代码片段)
实验六 继承定义与使用1、实验目的与要求(1) 理解继承的定义;(2) 掌握子类的定义要求(3) 掌握多态性的概念及用法;(4) 掌握抽象类的定义及用途;(5) 掌握类中4个成员访问权限修饰符的用途;(6) 掌握... 查看详情
201771010142张燕/杨蓉庆实验十三图形界面事件处理技术(代码片段)
实验十三 图形界面事件处理技术实验时间 2018-11-22 基础知识: ?事件源(eventsource):能够产生事件的对象都可以成为事件源,如文本框、按钮等。一个事件源是一个能够注册监听器并向监听器发送事件对象... 查看详情
java面对对象程序设计——面对对象(代码片段)
重点掌握1.类是对一类事物描述,是抽象的、概念上的定义;对象是实际存在的该类事物的每个个体,因而也称为实例2.创建对象的格式是:类名对象名称=new类名();3.方法的声明格式是:[<修饰符>]<返... 查看详情
面对对象的程序设计
面向对象(Object-Oriented,OO)的语言有一个标志,那就是它们都有类的概念,而通过类可以创建任意多个具有相同属性和方法的对象。 一、理解对象: 第一种:基于Object对象1varperson=newObject(... 查看详情
day-8:面对对象编程
面对过程的程序设计方法意在将函数分成子函数,再依次调用这些函数来解决问题。 而面对对象的程序设计方法,来源于自然界,类是实例的抽象,实例是类的具体。自定义出来的对象是类,而所有的数据都可以看成是... 查看详情
java面对对象程序设计——面对对象(代码片段)
重点掌握1.类是对一类事物描述,是抽象的、概念上的定义;对象是实际存在的该类事物的每个个体,因而也称为实例2.创建对象的格式是:类名对象名称=new类名();3.方法的声明格式是:[<修饰符>]<返... 查看详情
设计模式面对面之订阅模式
订阅模式订阅模式主要涉及到三种对象:订阅对象,发布对象,分发对象。案例没对这三种对象做抽像,大家可以根据应用场景去扩展。类图:常用的实现方式:订阅对象//订阅对象publicclassSubscribe{publicstringName;publicSubscribe(stringn... 查看详情
java面对对象入门-程序块初始化
Java实例初始化程序是在执行构造函数代码之前执行的代码块。每当我们创建一个新对象时,这些初始化程序就会运行。1.实例初始化语法用花括号创建实例初始化程序块。对象初始化语句写在括号内。publicclassDemoClass{//Thisisinitial... 查看详情
《设计模式之禅》笔记整理--面对对象设计六大原则
第一章、面对对象设计六大原则:(1)、单一职责原则:应该有且只有一个原因引起类的变更。为什么要用单一职责原则:(1)、类的复杂性降低,实现什么职责都有清晰明确的定义。 (2)、可读性提高,... 查看详情
java——面对对象
软件出现的目的:*用计算机的语言来描述世界*用计算机解决现实世界的问题面向对象的思想描述面向对象的世界面向对象设计和开发程序的好处:*交流更加流畅*提高设计和开发效率构造方法:构造方法是用来描述对象创建的... 查看详情
面对对象编程
面向对象编程标签(空格分隔):python基础---面向过程:根据业务逻辑从上到下写代码面向对象:将数据与函数绑定到一起,进行封装,这样能够更快速的开发程序,减少了重复代码的重写过程面向对象(object-oriented;简称:OO)至今... 查看详情