项目 |
内容 |
《面向对象程序设计(java)》 |
https://www.cnblogs.com/nwnu-daizh/ |
这个作业的要求在哪里 |
https://www.cnblogs.com/nwnu-daizh/p/11815810.html |
作业学习目标 |
|
1:总结第八章关于泛型程序设计理论知识
1. 泛型类的定义
a. 一个泛型类就是具有一个或多个类型变量的类,即创建用类型作为参数的类。
b. 泛型:也称参数化类型,就是定义类,接口和方法时,通过类型参数指示将要处理的对象类型。
2. 定义简单的泛型类:
a. public class Pair<T> Pair类引入了一个类型变量T,用<>括起来,并放在类名的后面。
b. 泛型类可以有多个类型变量 public class Pair<T,U>
c. 类的类型变量用于指定方法的返回类型以及域,局部变量的类型。
3. 泛型方法的声明:
a. 除了泛型类外,还可以只单独定义一个方法作为泛型方法,用于指定方法参数或者返回值为泛型类型,留待方法调用时确定。
b. 泛型方法可以声明在泛型类中,也可以在普通类中
class ArrayAlg
{
public static <T> getMiddle (T...a) {...}
}
4. 泛型接口的定义:
a. 定义: public interface IPool <T> {...}
b. 实现: publoc class GenericPool <T> implements IPool <T> {...}
5. 泛型变量的限定
a. 定义泛型变量的上界 : public class NumberGeneric <T extends Number>
• 上述声明规定了NumberGeneric类所能处理的泛型变量类型需和Number有继承关系;
• extends 关键字所声明的上界既可以是一个类,也可以是一个接口;
• T 应该是绑定类型的子类型;
• 一个类型变量或通配符可以有多个限定,限定类型用" &" 分割。 <T extends Comparable & Serializable>
b. 定义泛型变量的下界 : public static <T > void sort (T[] a, Comparator <? super T> c) {...}
• 通过super关键字可以固定泛型参数 T 的类型为某种类型的 超类;
• 当希望为一个方法的参数限定类型时,通常可以使用下限通配符
6. 通配符的类型
通配符 " ? " 表示参数类型可以是任何一种类型。
用法: a. 单独的 " ?" ,用于表示任何类型;
b. ? ertends type, 表示带有上界;
c. ? super type,表示带有下界。
7. 泛型程序设计小结:
a. 定义一个泛型类时,在"<>" 定义形式类型参数 class Test < K , V> , K,V 表示类型
b. 实例化泛型对象的时候, 一定要在类名后面指定类型参数的值(类型), 一共要有两次书写, Test <String , String> t = new Test <String, String>();
c. 泛型中 <T extends Object> , extends并不代表继承,它是类型范围的限制;
d. 泛型类不是协变的。
2、实验内容和步骤
实验1: 导入第8章示例程序,测试程序并进行代码注释。
测试程序1:
1 package Pair; 2 public class Pair<T> //泛型类Pair引入了一个泛型参数 T 3 { 4 private T first; 5 private T second; 6 7 public Pair() { first = null; second = null; } 8 public Pair(T first, T second) { this.first = first; this.second = second; } 9 10 public T getFirst() { return first; } 11 public T getSecond() { return second; } 12 13 public void setFirst(T newValue) { first = newValue; } 14 public void setSecond(T newValue) { second = newValue; } 15 }
1 package Pair; 2 public class PairTest1 3 { 4 public static void main(String[] args) 5 { 6 String[] words = { "Mary", "had", "a", "little", "lamb" }; 7 Pair<String> mm = ArrayAlg.minmax(words); //使用泛型类Pair<String>定义泛型变量 8 System.out.println("min = " + mm.getFirst()); 9 System.out.println("max = " + mm.getSecond()); 10 } 11 } 12 13 class ArrayAlg 14 { 15 /** 16 * Gets the minimum and maximum of an array of strings. 17 * @param a an array of strings 18 * @return a pair with the min and max values, or null if a is null or empty 19 */ 20 public static Pair<String> minmax(String[] a) //定义一个泛型方法 21 { 22 if (a == null || a.length == 0) return null; 23 String min = a[0]; 24 String max = a[0]; 25 for (int i = 1; i < a.length; i++) 26 { 27 if (min.compareTo(a[i]) > 0) min = a[i]; 28 if (max.compareTo(a[i]) < 0) max = a[i]; 29 } 30 return new Pair<>(min, max);//返回Pair<String>类对象 31 } 32 }
运行结果如下:
测试程序2:
1 package pair2; 2 3 import java.time.*; 4 5 import Pair.Pair; 6 7 /** 8 * @version 1.02 2015-06-21 9 * @author Cay Horstmann 10 */ 11 public class PairTest2 12 { 13 public static void main(String[] args) 14 { 15 LocalDate[] birthdays = 16 { 17 LocalDate.of(1906, 12, 9), // G. Hopper 18 LocalDate.of(1815, 12, 10), // A. Lovelace 19 LocalDate.of(1903, 12, 3), // J. von Neumann 20 LocalDate.of(1910, 6, 22), // K. Zuse 21 }; 22 Pair<LocalDate> mm = ArrayAlg.minmax(birthdays); //使用泛型类Pair<String>定义泛型变量 23 System.out.println("min = " + mm.getFirst()); 24 System.out.println("max = " + mm.getSecond()); 25 } 26 } 27 28 class ArrayAlg 29 { 30 /** 31 Gets the minimum and maximum of an array of objects of type T. 32 @param a an array of objects of type T 33 @return a pair with the min and max values, or null if a is null or empty 34 */ 35 public static <T extends Comparable> Pair<T> minmax(T[] a) //对泛型参数T设置了一个上界 36 { 37 if (a == null || a.length == 0) return null; 38 T min = a[0]; 39 T max = a[0]; 40 for (int i = 1; i < a.length; i++) 41 { 42 if (min.compareTo(a[i]) > 0) min = a[i]; 43 if (max.compareTo(a[i]) < 0) max = a[i]; 44 } 45 return new Pair<>(min, max); //返回Pair<>类对象 46 } 47 }
运行结果如下:
测试程序3:
1 package pair3; 2 3 import java.time.*; 4 5 public class Employee 6 { 7 private String name; 8 private double salary; 9 private LocalDate hireDay; 10 11 public Employee(String name, double salary, int year, int month, int day) 12 { 13 this.name = name; 14 this.salary = salary; 15 hireDay = LocalDate.of(year, month, day); 16 } 17 18 public String getName() 19 { 20 return name; 21 } 22 23 public double getSalary() 24 { 25 return salary; 26 } 27 28 public LocalDate getHireDay() 29 { 30 return hireDay; 31 } 32 33 public void raiseSalary(double byPercent) 34 { 35 double raise = salary * byPercent / 100; 36 salary += raise; 37 } 38 }
1 package pair3; 2 3 public class Manager extends Employee 4 { 5 private double bonus; 6 public Manager(String name, double salary, int year, int month, int day) 7 { 8 super(name, salary, year, month, day); 9 bonus = 0; 10 } 11 12 public double getSalary() 13 { 14 double baseSalary = super.getSalary(); 15 return baseSalary + bonus; 16 } 17 18 public void setBonus(double b) 19 { 20 bonus = b; 21 } 22 23 public double getBonus() 24 { 25 return bonus; 26 } 27 }
1 package pair3; 2 import Pair.Pair; 3 public class PairTest3 4 { 5 public static void main(String[] args) 6 { 7 //创建Manager类对象 8 Manager ceo = new Manager("Gus Greedy", 800000, 2003, 12, 15); 9 Manager cfo = new Manager("Sid Sneaky", 600000, 2003, 12, 15); 10 Pair<Manager> buddies = new Pair<Manager>(ceo, cfo); // 创建泛型类对象 11 printBuddies(buddies); 12 13 ceo.setBonus(1000000); 14 cfo.setBonus(500000); 15 Manager[] managers = { ceo, cfo }; 16 17 Pair<Employee> result = new Pair<Employee>(); // 创建泛型类对象 18 minmaxBonus(managers, result); 19 System.out.println("first: " + result.getFirst().getName() 20 + ", second: " + result.getSecond().getName()); 21 maxminBonus(managers, result); 22 System.out.println("first: " + result.getFirst().getName() 23 + ", second: " + result.getSecond().getName()); 24 } 25 26 public static void printBuddies(Pair<? extends Employee> p) //表示任何泛型Pair类型,它的参数类型是Employee子类。 ?表示通配符类型 27 { 28 Employee first = p.getFirst(); 29 Employee second = p.getSecond(); 30 System.out.println(first.getName() + " and " + second.getName() + " are buddies."); 31 } 32 33 public static void minmaxBonus(Manager[] a, Pair<? super Manager> result) //<? super Manager> 限制为Manager的所有超类型 34 { 35 if (a.length == 0) return; 36 Manager min = a[0]; 37 Manager max = a[0]; 38 for (int i = 1; i < a.length; i++) 39 { 40 if (min.getBonus() > a[i].getBonus()) min = a[i]; 41 if (max.getBonus() < a[i].getBonus()) max = a[i]; 42 } 43 result.setFirst(min); 44 result.setSecond(max); 45 } 46 47 public static void maxminBonus(Manager[] a, Pair<? super Manager> result) 48 { 49 minmaxBonus(a, result); 50 PairAlg.swapHelper(result); // OK--swapHelper captures wildcard type 51 } 52 // can't write public static <T super manager> . . . 53 } 54 55 class PairAlg 56 { 57 public static boolean hasNulls(Pair<?> p)//使用无限定通配符用来测试一个Pair是否包含一个null引用 58 { 59 return p.getFirst() == null || p.getSecond() == null; 60 } 61 62 public static void swap(Pair<?> p) { swapHelper(p); } // swap调用swapHelper方法 63 64 public static <T> void swapHelper(Pair<T> p) //swapHelper是一个泛型方法 65 { 66 T t = p.getFirst(); 67 p.setFirst(p.getSecond()); 68 p.setSecond(t); 69 } 70 }
运行结果如下:
实验2:结对编程练习,将程序提交到PTA(2019面向对象程序设计基础知识测试题(2))
(1) 编写一个泛型接口GeneralStack,要求类中方法对任何引用类型数据都适用。GeneralStack接口中方法如下:
push(item); //如item为null,则不入栈直接返回null。 pop(); //出栈,如为栈为空,则返回null。 peek(); //获得栈顶元素,如为空,则返回null. public boolean empty();//如为空返回true public int size(); //返回栈中元素数量 |
(2)定义GeneralStack的子类ArrayListGeneralStack,要求:
类内使用ArrayList对象存储堆栈数据,名为list; 方法: public String toString()//代码为return list.toString(); 代码中不要出现类型不安全的强制转换。 |
(3)定义Car类,类的属性有:
private int id; private String name; |
方法:Eclipse自动生成setter/getter,toString方法。
(4)main方法要求
输入选项,有quit, Integer, Double, Car 4个选项。如果输入quit,程序直接退出。否则,输入整数m与n。m代表入栈个数,n代表出栈个数。然后声明栈变量stack。 输入Integer,打印Integer Test。建立可以存放Integer类型的ArrayListGeneralStack。入栈m次,出栈n次。打印栈的toString方法。最后将栈中剩余元素出栈并累加输出。 输入Double ,打印Double Test。剩下的与输入Integer一样。 输入Car,打印Car Test。其他操作与Integer、Double基本一样。只不过最后将栈中元素出栈,并将其name依次输出。 |
特别注意:如果栈为空,继续出栈,返回null
输入样例
Integer 5 2 1 2 3 4 5 Double 5 3 1.1 2.0 4.9 5.7 7.2 Car 3 2 1 Ford 2 Cherry 3 BYD quit |
输出样例
Integer Test push:1 push:2 push:3 push:4 push:5 pop:5 pop:4 [1, 2, 3] sum=6 interface GeneralStack Double Test push:1.1 push:2.0 push:4.9 push:5.7 push:7.2 pop:7.2 pop:5.7 pop:4.9 [1.1, 2.0] sum=3.1 interface GeneralStack Car Test push:Car [id=1, name=Ford] push:Car [id=2, name=Cherry] push:Car [id=3, name=BYD] pop:Car [id=3, name=BYD] pop:Car [id=2, name=Cherry] [Car [id=1, name=Ford]] Ford interface GeneralStack |
1 package tuxing; 2 import java.util.ArrayList; 3 import java.util.Scanner; 4 5 interface GeneralStack<T> 6 { 7 public T push(T item); //如item为null,则不入栈直接返回null。 8 public T pop(); //出栈,如为栈为空,则返回null。 9 public T peek(); //获得栈顶元素,如为空,则返回null. 10 public boolean empty(); //如为空返回true 11 public int size(); //返回栈中元素数量 12 } 13 class ArrayListGeneralStack implements GeneralStack 14 { 15 16 ArrayList list = new ArrayList(); 17 public String toString() 18 { 19 return list.toString(); 20 } 21 @Override 22 public Object push(Object item) { 23 if (list.add(item)){ 24 return item; 25 }else { 26 return false; 27 } 28 } 29 30 @Override 31 public Object pop() { 32 if (list.size()==0){ 33 return null;} 34 return list.remove(list.size()-1); 35 } 36 37 @Override 38 public Object peek() { 39 if(list.size()!=0) 40 return list.get(list.size()-1); 41 return null; 42 } 43 44 @Override 45 public boolean empty() { 46 if(list.size()==0) 47 return true; 48 return false; 49 } 50 51 @Override 52 public int size() { 53 // TODO Auto-generated method stub 54 return list.size(); 55 } 56 57 } 58 59 class Car 60 { 61 private int id; 62 private String name; 63 64 @Override 65 public String toString() { 66 return "Car [" + "id=" + id +", name=" + getName() +']'; 67 } 68 69 public int getId() { 70 return id; 71 } 72 73 public void setId(int id) { 74 this.id = id; 75 } 76 77 public String getName() { 78 return name; 79 } 80 81 public void setName(String name) { 82 this.name = name; 83 } 84 public Car(int id, String name) { 85 this.id = id; 86 this.setName(name); 87 } 88 } 89 public class Main { 90 91 public static void main(String[] args) { 92 Scanner in = new Scanner(System.in); 93 while(true){ 94 String c = in.nextLine(); 95 if(c.equals("Integer")) 96 { 97 System.out.println("Integer Test"); 98 int m=in.nextInt(); 99 int n=in.nextInt(); 100 ArrayListGeneralStack array = new ArrayListGeneralStack(); 101 for(int i=0;i<m;i++) 102 { 103 System.out.println("push:"+array.push(in.nextInt())); 104 } 105 for(int i=0;i<n;i++) 106 { 107 System.out.println("pop:"+array.pop()); 108 } 109 System.out.println(array.toString()); 110 int sum=0; 111 int size=array.size(); 112 for(int i=0;i<size;i++) 113 { 114 sum+=(int)array.pop(); 115 } 116 System.out.println("sum="+sum); 117 System.out.println("interface GeneralStack"); 118 } 119 else if(c.equals("Double")) 120 { 121 System.out.println("Double Test"); 122 int m = in.nextInt(); 123 int n = in.nextInt(); 124 ArrayListGeneralStack array = new ArrayListGeneralStack(); 125 for (int i=0;i<m;i++) 126 { 127 System.out.println("push:"+array.push(in.nextDouble())); 128 } 129 for(int i=0;i<n;i++) 130 { 131 System.out.println("pop:"+array.pop()); 132 } 133 System.out.println(array.toString()); 134 double sum=0; 135 int size=array.size(); 136 for(int i =0;i<size;i++) 137 { 138 sum+=(double)array.pop(); 139 } 140 System.out.println("sum="+sum); 141 System.out.println("interface GeneralStack"); 142 } 143 else if(c.equals("Car")) 144 { 145 System.out.println("Cat Test"); 146 int m=in.nextInt(); 147 int n=in.nextInt(); 148 ArrayListGeneralStack array = new ArrayListGeneralStack(); 149 for(int i=0;i<m;i++) 150 { 151 int id = in.nextInt(); 152 String name = in.next(); 153 Car car = new Car(id, name); 154 System.out.println("push"+array.push(car)); 155 } 156 for(int i =0;i<n;i++) 157 { 158 System.out.println("pop"+array.pop()); 159 } 160 System.out.println(array.toString()); 161 int size=array.size(); 162 for(int i=0;i<size;i++) 163 { 164 Car car=(Car) array.pop(); 165 System.out.println(car.getName()); 166 } 167 168 System.out.println("interface GeneralStack"); 169 } 170 else if (c.equals("quit")){ 171 System.exit(0);; 172 }} 173 } 174 }
结果:
实验总结: 在本节中我知道了泛型类的定义,泛型方法的声明,泛型接口的定义,类型变量的限定,包括上界,下界,还有通配符类型。收获还是可以的,就是编程的时候遇到了一些困难,然后通过上网搜查和问同学,有的问题解决了,但有的问题还是懵懵懂懂。就是在PTA上交不上去,出现了一些未经检查或不安全的操作。就这个问题弄了好长的时间。