项目

内容

《面向对象程序设计(java)》

https://www.cnblogs.com/nwnu-daizh/

这个作业的要求在哪里

https://www.cnblogs.com/nwnu-daizh/p/11815810.html

作业学习目标

  1. 理解泛型概念;
  2. 掌握泛型类的定义与使用;
  3. 掌握泛型方法的声明与使用;
  4. 掌握泛型接口的定义与实现;
  5. 了解泛型程序设计,理解其用途。

第一部分:总结第八章关于泛型程序设计理论知识

一、泛型:

泛型本质是指类型参数化。意思是允许在定义类、接口、方法时使用类型形参,当使用时指定具体类型,所有使用该泛型参数的地方都被统一化,保证类型一致。如果未指定具体类型,默认是Object类型。集合体系中的所有类都增加了泛型,泛型也主要用在集合。

二、泛型的定义:

泛型类:public class Demo<T> {} ,T表示未知类型。
泛型接口:public interface ImplDemo<T,V>{} ,和定义类一样(接口就是一个特殊类)。
泛型方法:public <T>  void demo1(T name){System.out.println(name);} , public <T> T demo2(T t){ return t;}
三、泛型的好处
  1. 编译时确定类型,保证类型安全,避免类型转换异常。
  2. 避免了强制类型转换。
  3. 代码利于重用,增加通用性。

四、泛型的限制和规则

  • 泛型的类型参数只能是引用类型,不能使用值类型。
  • 泛型的类型参数可以有多个。
  • 泛型类不是真正存在的类,不能使用instanceof运算符。
  • 泛型类的类型参数不能用在静态申明。
  • 如果定义了泛型,不指定具体类型,泛型默认指定为Ojbect类型。
  • 泛型使用?作为类型通配符,表示未知类型,可以匹配任何类型。因为是未知,所以无法添加元素。
  • 类型通配符上限:<? extends T>,?代表是T类型本身或者是T的子类型。常用于泛型方法,避免类型转换。
  • 类型通配符下限。<? super T>,?代表T类型本身或者是T的父类型。
  • 除了通配符可以实现限制,类、接口和方法中定义的泛型参数也能限制上限和下限。

五、泛型的几个概述

1:从Java程序设计语言1.0版发布以来,变化最大的部分就是泛型。

2:使用泛型机制编写的程序代码要比那些杂乱的使用Object变量,然后在进行强制类型转换的的代码具有更好的安全性和可读性。

3:泛型程序设计意味着编写的代码可以被很多不同类型的对象所重用。

4:在Java中增加泛型类之前,泛型程序设计是用继承实现的,使用这种方法有两个问题:当获取一个值时必须进行强制类型转换;此外这里也没有错误检查,也就是说可以向数组列表中添加任何类的对象。

5:泛型通过提供一个类型参数,用来指示元素类型,从而解决了使用继承实现泛型的弊端,使得程序具有更好的可读性和安全性。

六、泛型代码示例

1、集合类演示泛型

  1. //未指定泛型
  2. TreeSet ts = new TreeSet();
  3. ts.add(10);
  4. ts.add(25);
  5. ts.add("30");
  6. System.out.println(ts);//运行时报错,类型转换异常
  7.  
  8. //mode 2
  9. TreeSet<Integer> ts2 = new TreeSet<>();
  10. ts2.add(10);
  11. ts2.add(25);
  12. ts2.add("30"); //编译器提示报错,无法添加非Integer类型

未使用泛型时,可以添加任意元素,因为TreeSet会比较每一个元素,所以运行时会引发类型转换异常。使用泛型后,只能添加同一个类型,所以不会出错。

2、定义泛型类

  1. public class Person<T> {
  2. private T name;//类型是未知的
  3.  
  4. public Person(T name) {
  5. this.name = name;
  6. }
  7.  
  8. public T getName() {
  9. return name;
  10. }
  11.  
  12. public void sexName(T name) {
  13. this.name = name;
  14. }
  15.  
  16. }

在上面实例中,Person类定义成泛型类,成员变量name的类型指定为T,表示未知类型。实例化该类对象后,可以看到name的类型是Object,表示可以接收任何类型。

  1. Person p = new Person(10); //new Person(Object name)

加上泛型后

  1. //使用泛型两种方式
  2. Person<String> ps = new Person<String>(); //new Person<String>(String name)
  3. Person<String> ps = new Person<>();//new Person<>(T name)

第一种,会直接确定参数类型是什么,而第二种的参数类型是T ,但如果加入的非String类型,编译器会检查并报错。两者区别不大。在JDK1.7之后使用第二种,会自动检查泛型,可以省略后部分<>的泛型参数,建议使用第二种。

3、定义泛型接口

  1. interface A<T>{
  2. void display(T value);
  3. T getValue(T v);
  4. }
  5.  
  6. //未对泛型接口指定具体类型
  7. public class Person implements A{
  8.  
  9. @Override
  10. public void display(Object obj) {
  11. System.out.println();
  12. }
  13.  
  14. @Override
  15. public Object getValue(Object v) {
  16. return null;
  17. }
  18.  
  19. }

如果我们定义了泛型,不指定具体类型,默认就是Object类型。当我们为泛型接口指定具体类型后,代码如下:

  1. //泛型接口
  2. interface A<T>{
  3. void display(T value);
  4. T getValue(T v);
  5. }
  6.  
  7. //为泛型接口指定具体类型
  8. public class Person implements A<String>{
  9. @Override
  10. public void display(String value) {
  11. }
  12. @Override
  13. public String getValue(String v) {
  14. return null;
  15. }
  16. }

泛型接口指定具体类型后,所有使用了该泛型参数的地方都被统一化。其实泛型接口和泛型类是一样的写法。

4、定义泛型方法

先使用常规方法进行对比。

  1. public static void main(String[] args) {
  2. int[] arr = new int[] {1, 8, 15, 6, 3};
  3. double[] douArr = {10.5, 25.1, 4.9, 1.8};
  4. String[] strArr = {"我","是","字","符","串"};
  5. forArr(strArr);
  6.  
  7. }
  8.  
  9. //遍历数组的重载方法,支持int和double类型
  10. public static void forArr(int[] arr) {
  11. for(int i=0; i<arr.length; i++) {
  12. System.out.println(arr[i]);
  13. }
  14. }
  15. //重载了
  16. public static void forArr(double[] arr) {
  17. for(double d : arr) {
  18. System.out.println(d);
  19. }
  20. }
  21. //……
  22. //……

如上所示,如果想遍历Stirng类型数组,那就还要再次重载代码,如果是八种类型都有,代码量非常庞大。使用泛型方法全部通用,代码如下:

  1. public static void main(String[] args) {
  2. Integer[] arr = {1, 8, 15, 6, 3};
  3. Double[] douArr = {10.5, 25.1, 4.9, 1.8};
  4. String[] strArr = {"我","是","字","符","串"};
  5.  
  6. forArrGenric(strArr);
  7.  
  8. }
  9. //泛型方法
  10. public static <T> void forArrGenric(T[] arr) {
  11. for(int i=0; i < arr.length; i++) {
  12. System.out.println(arr[i]);
  13. }
  14. }

只需定义一个泛型方法,根据运行时传入的参数类型,动态地获取类型,就能做到遍历所有类型数组。但需要注意,泛型的类型参数只能是引用类型,值类型无法在泛型中使用,所以上面的数组都改成了引用类型。值类型需要使用对应的包装类类型。

七、类型变量的限定

1、泛型变量的上界:如<T extends Number>(extends关键字所声明的上界既可以是一个类,也可以是一个接口,extends并不代表继承,它是类型范围限制。)

2、<T  extends   Bounding   Type>表示T应该是绑定类型的子类型。

3、一个类型变量和通配符可以有多个限定,限定类型用“&”分割。eg:<T  entends  Compareable   &   Seriaizable>

八、泛型类型的继承规则

1、Java中的数组是协变的(covariant)。例如:Integer扩展了Number,那么在要求Number[]的地方完全可以传递或者赋予Integer[],Number[]也是Integer[]的超类型。

2、Employee是Manager的超类,因此可以将一个Manager[]数组赋给一个类型为Employee[]的变量: Manager[] managerBuddies = {ceo, cfo};

Employee[] employeeBuddies = managerBuddies;

但这一原理不适用于泛型类型。例如:

Pair<Manager> managerBuddies = new Pair<Manager>(ceo, cfo);

Pair<Employee> employeeBuddies = managerBuddies;  //illegal
    employeeBuddies.setFirst(lowlyEmployee);不允许这样做的理由:避免破坏要提供类型的安全泛型。

3、Java中泛型类不具协变性。如果能够将List<Integer>赋给 List<Number>。那么下面的代码就允许将非Integer的内容放入 List<Integer>:

List<Integer> li = new ArrayList<Integer>();

List<Number> ln = li; // illegal

ln.add(new Float(3.1415));

4、泛型类可扩展或实现其它的泛型类。例如,ArrayList<T>类实现List<T>接口。这意味着,一个ArrayList<Manager>可以被转换为一个List<Manager>。

九、泛型类的约束与局限性

1、不能用基本类型实例化类型参数

2、运行时类型查询只适用于原始类型

3、不能抛出也不能捕获泛型类实例

4、参数化类型的数组不合法

5、参数化类型的数组不合法

6、泛型类的静态上下文中类型变量无效

十、通配符类型

1、通配符:“?”符号表明参数的类型可以是任何一种类型,而T表示一种未知类型。

2、通配符的一般用法:a.?:用于表示任何类型;

b.? extends type,表示带有上界;

c.? super type,表示带有下界。

3、无界通配符(*):   Pair< ? >

4、通配符“?”同样可以对类型进行限定。可以分为子类型限定、超类型限定和无限定。通配符不是类型变量,因此不能在代码中使用"?"作为一种类型。

第二部分:实验部分

1、实验目的与要求

(1) 理解泛型概念;

(2) 掌握泛型类的定义与使用;

(3) 了解泛型方法的声明与使用;

(4) 掌握泛型接口的定义与实现;

(5) 理解泛型程序设计,理解其用途。

2、实验内容和步骤

实验1 导入第8章示例程序,测试程序并进行代码注释。

测试程序1:

编辑、调试、运行教材311312页代码,结合程序运行结果理解程序;

在泛型类定义及使用代码处添加注释;

掌握泛型类的定义及使用。

Pair程序代码如下:

  1. package pair1;
  2.  
  3. /**
  4. * @version 1.00 2004-05-10
  5. * @author Cay Horstmann
  6. */
  7. public class Pair<T> //定义一个泛型类Pair,并在该类中引入一个变量T(表示任意类型)
  8. {
  9. private T first;
  10. private T second;
  11. //泛型声明时不能使用静态方法或静态属性
  12. public Pair() { first = null; second = null; }
  13. public Pair(T first, T second) { this.first = first; this.second = second; }
  14.  
  15. public T getFirst() { return first; }
  16. public T getSecond() { return second; }
  17.  
  18. public void setFirst(T newValue) { first = newValue; }
  19. public void setSecond(T newValue) { second = newValue; }
  20. }

PairTest1 程序代码如下:

  1. package pair1;
    /**
  2. * @version 1.01 2012-01-26
  3. * @author Cay Horstmann
  4. */
  5. public class PairTest1
  6. {
  7. public static void main(String[] args)
  8. {
    //引用时指定类型(引用类型)
  9. String[] words = { "Mary", "had", "a", "little", "lamb" };//调用泛型方法
  10. Pair<String> mm = ArrayAlg.minmax(words);
  11. System.out.println("min = " + mm.getFirst());
  12. System.out.println("max = " + mm.getSecond());
  13. }
  14. }
  15.  
  16. class ArrayAlg
  17. {
  18. /**
  19. * Gets the minimum and maximum of an array of strings.
  20. * @param a an array of strings
  21. * @return a pair with the min and max values, or null if a is null or empty
  22. */
  23. public static Pair<String> minmax(String[] a)//将泛型利用到方法上就可以定义一个泛型方法
    //注意将类型变量放到修饰符的后面,返回类型的前面。当调用一个泛型方法时,在方法名前的尖括号中放入具体的类型。当然,如果参数不存在类型转换问题,编译器有足够的信息可以推断出参数类型,则可以省略。
  24. {
  25. if (a == null || a.length == 0) return null;
  26. String min = a[0];
  27. String max = a[0];
  28. for (int i = 1; i < a.length; i++)
  29. {
  30. if (min.compareTo(a[i]) > 0) min = a[i];
  31. if (max.compareTo(a[i]) < 0) max = a[i];
  32. }
  33. return new Pair<>(min, max);
  34. }
  35. }

程序运行结果如下:

测试程序2:

编辑、调试运行教材315 PairTest2,结合程序运行结果理解程序;

在泛型程序设计代码处添加相关注释;

了解泛型方法、泛型变量限定的定义及用途。

Pair程序代码如下:

  1. package pair2;
  2.  
  3. /**
  4. * @version 1.00 2004-05-10
  5. * @author Cay Horstmann
  6. */
  7. public class Pair<T>{ //定义一个泛型类Pair,并在该类中引入一个变量T
  1. private T first;
    private T second;
  1. public Pair() {
    first = null;
    second = null;
    }
    public Pair(T first, T second)
    { this.first = first;
    this.second = second; }
  2. public T getFirst() { return first; }
    public T getSecond() { return second; }
  3. public void setFirst(T newValue) { first = newValue; }
    public void setSecond(T newValue) { second = newValue; } }

PairTest2程序代码如下:

  1. package pair2;
    import java.time.*;
  2. /**
  3. * @version 1.02 2015-06-21
  4. * @author Cay Horstmann
  5. */
  6. public class PairTest2
  7. {
  8. public static void main(String[] args)
  9. {
  10. LocalDate[] birthdays =
  11. {
  12. LocalDate.of(1906, 12, 9), // G. Hopper
  13. LocalDate.of(1815, 12, 10), // A. Lovelace
  14. LocalDate.of(1903, 12, 3), // J. von Neumann
  15. LocalDate.of(1910, 6, 22), // K. Zuse
  16. };
  17. Pair<LocalDate> mm = ArrayAlg.minmax(birthdays);//这是一个泛型方法,从尖括号和类型变量可以看出
  18. System.out.println("min = " + mm.getFirst());
  19. System.out.println("max = " + mm.getSecond());
  20. }
  21. }
  22. class ArrayAlg//创建一个泛型类
  23. {
  24. /**
  25. Gets the minimum and maximum of an array of objects of type T.
  26. @param a an array of objects of type T
  27. @return a pair with the min and max values, or null if a is null or empty
  28. */
  29. public static <T extends Comparable> Pair<T> minmax(T[] a) /*对类型变量T设置限定,通过指定< T extends Comparable >
    表明类型参数需要是实现Comparable接口的类(这里T表示的是绑定类型的子类型。T和绑定类型可以是类,也可以是接口)*/
  30. {
  31. if (a == null || a.length == 0) return null;
  32. T min = a[0];
  33. T max = a[0];//变量min和max类型是T
  34. for (int i = 1; i < a.length; i++)
  35. {
  36. if (min.compareTo(a[i]) > 0) min = a[i];
  37. if (max.compareTo(a[i]) < 0) max = a[i];
  38. }
  39. return new Pair<>(min, max);返回泛型类
  40. }
  41. }

运行结果如下:

小结:我们发现,在这个程序中泛型方法并不是在泛型类中定义的,也就是说,泛型方法不一定非得定义在泛型类中。在对类型变量的限定中,我们使用了extends关键字,意思就是只有实现了Comparable接口的类才可以使用这个泛型方法。

测试程序3:

用调试运行教材335 PairTest3,结合程序运行结果理解程序;

了解通配符类型的定义及用途。

Pair程序代码如下:

  1. package pair3;
  2.  
  3. /**
  4. * @version 1.00 2004-05-10
  5. * @author Cay Horstmann
  6. */
  7. public class Pair<T>
  8. {
  9. private T first;
  10. private T second;
  11. //构造器
  12. public Pair() { first = null; second = null; }
  13. public Pair(T first, T second) { this.first = first; this.second = second; }
  14. //get方法
  15. public T getFirst() { return first; }
  16. public T getSecond() { return second; }
  17. //set方法
  18. public void setFirst(T newValue) { first = newValue; }//
  19. public void setSecond(T newValue) { second = newValue; }
  20. }

PairTest3程序代码如下:

  1. package pair3;
  2.  
  3. /**
  4. * @version 1.01 2012-01-26
  5. * @author Cay Horstmann
  6. */
  7. public class PairTest3
  8. {
  9. public static void main(String[] args)
  10. {
  11. var ceo = new Manager("Gus Greedy", 800000, 2003, 12, 15);
  12. var cfo = new Manager("Sid Sneaky", 600000, 2003, 12, 15);
  13. var buddies = new Pair<Manager>(ceo, cfo);
  14. printBuddies(buddies);
  15.  
  16. ceo.setBonus(1000000);
  17. cfo.setBonus(500000);
  18. Manager[] managers = { ceo, cfo };//创建一个manger数组
  19.  
  20. var result = new Pair<Employee>();//创建一个泛型类对象
  21. minmaxBonus(managers, result);
  22. System.out.println("first: " + result.getFirst().getName()
  23. + ", second: " + result.getSecond().getName());
  24. maxminBonus(managers, result);
  25. System.out.println("first: " + result.getFirst().getName()
  26. + ", second: " + result.getSecond().getName());
  27. }
  28.  
  29. public static void printBuddies(Pair<? extends Employee> p)
  30. {
  31. Employee first = p.getFirst();
  32. Employee second = p.getSecond();
  33. System.out.println(first.getName() + " and " + second.getName() + " are buddies.");
  34. }
  35.  
  36. public static void minmaxBonus(Manager[] a, Pair<? super Manager> result)
  37. {
  38. if (a.length == 0) return;
  39. Manager min = a[0];
  40. Manager max = a[0];
  41. for (int i = 1; i < a.length; i++)
  42. {
  43. if (min.getBonus() > a[i].getBonus()) min = a[i];
  44. if (max.getBonus() < a[i].getBonus()) max = a[i];
  45. }
  46. result.setFirst(min);
  47. result.setSecond(max);
  48. }
  49.  
  50. public static void maxminBonus(Manager[] a, Pair<? super Manager> result)
  51. {
  52. minmaxBonus(a, result);
  53. PairAlg.swapHelper(result); // OK--swapHelper captures wildcard type
  54. }
  55. // can't write public static <T super manager> . . .
  56. }
  57.  
  58. class PairAlg
  59. {
  60. public static boolean hasNulls(Pair<?> p)//调用hasNulls方法
  61. {
  62. return p.getFirst() == null || p.getSecond() == null;
  63. }
  64.  
  65. public static void swap(Pair<?> p) { swapHelper(p); }//调用swap方法
  66.  
  67. public static <T> void swapHelper(Pair<T> p)//定义一个泛型类变量T
  68. {
  69. T t = p.getFirst();
  70. p.setFirst(p.getSecond());
  71. p.setSecond(t);
  72. }
  73. }

Employee程序代码如下:

  1. package pair3;
  2.  
  3. import java.time.*;
  4.  
  5. public class Employee
  6. {
  7. private String name;//private定义了一个只能在该类中访问的字符串变
  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. }

Manager程序代码如下:

  1. package pair3;
  2.  
  3. public class Manager extends Employee//扩展了一个子类Manager
  4. {
  5. private double bonus;
  6.  
  7. /**
  8. @param name the employee's name
  9. @param salary the salary
  10. @param year the hire year
  11. @param month the hire month
  12. @param day the hire day
  13. */
  14. public Manager(String name, double salary, int year, int month, int day)
  15. {
  16. super(name, salary, year, month, day);//调用了父类的构造
  17. bonus = 0;
  18. }
  19.  
  20. public double getSalary()
  21. {
  22. double baseSalary = super.getSalary();//调用父类的方法
  23. return baseSalary + bonus;//可以重写父类的方法
  24. }
  25.  
  26. public void setBonus(double b)
  27. {
  28. bonus = b;
  29. }//构造器
  30.  
  31. public double getBonus()
  32. {
  33. return bonus;
  34. }
  35. }

运行结果如下:

实验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方法。

4main方法要求

ü 输入选项,有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. import java.util.ArrayList;
  2. import java.util.Scanner;
  3.  
  4. interface GeneralStack<T>{
  5. public T push(T item); //如item为null,则不入栈直接返回null。
  6. public T pop(); //出栈,如为栈为空,则返回null。
  7. public T peek(); //获得栈顶元素,如为空,则返回null.
  8. public boolean empty();//如为空返回true
  9. public int size(); //返回栈中元素数量
  10. }
  11. class ArrayListGeneralStack implements GeneralStack{ //创建一个实现GeneralStack接口的类
  12. ArrayList list=new ArrayList();
  13. @Override//重写toString方法
  14. public String toString() {
  15. return list.toString();
  16. }
  17.  
  18. @Override//重写压栈方法
  19. public Object push(Object item) {
  20. if (list.add(item)){
  21. return item;
  22. }else {
  23. return false;
  24. }
  25. }
  26.  
  27. @Override//重写出栈方法
  28. public Object pop() {
  29. if (list.size()==0){//判断栈为空时,返回null
  30. return null;
  31. }
  32. return list.remove(list.size()-1);
  33. }
  34.  
  35. @Override//重写获取栈顶元素的函数
  36. public Object peek() {
  37. return list.get(list.size()-1);
  38. }
  39.  
  40. @Override
  41. public boolean empty() {//栈为空时,直接返回boolean值
  42. if (list.size()==0){
  43. return true;
  44. }else {
  45. return false;
  46. }
  47. }
  48.  
  49. @Override//重写得到栈中元素个数的函数
  50. public int size() {
  51. return list.size();
  52. }
  53. }
  54. class Car{//定义一个Car类
  55. private int id;//两个私有属性
  56. private String name;
  57.  
  58. @Override
  59. public String toString() {
  60. return "Car [" +
  61. "id=" + id +
  62. ", name=" + name +
  63. ']';
  64. }
  65.  
  66. public int getId() {
  67. return id;
  68. }
  69.  
  70. public void setId(int id) {
  71. this.id = id;
  72. }
  73.  
  74. public String getName() {
  75. return name;
  76. }
  77.  
  78. public void setName(String name) {
  79. this.name = name;
  80. }
  81.  
  82. public Car(int id, String name) {
  83. this.id = id;
  84. this.name = name;
  85. }
  86. }
  87. public class Main {
  88. public static void main(String[] args) {
  89. Scanner sc=new Scanner(System.in);
  90. while (true){
  91. String s=sc.nextLine();//输入选项,有quit, Integer, Double, Car 4个选项。
  92. if (s.equals("Double")){//输入Double ,打印Double Test。
  93. System.out.println("Double Test");
  94. int count=sc.nextInt();
  95. int pop_time=sc.nextInt();
  96. ArrayListGeneralStack arrayListGeneralStack = new ArrayListGeneralStack();//建立可以存放Double类型的ArrayListGeneralStack。
  97. for (int i=0;i<count;i++){//入栈次数
  98. System.out.println("push:"+arrayListGeneralStack.push(sc.nextDouble()));
  99. }
  100. for (int i=0;i<pop_time;i++){//出栈次数
  101. System.out.println("pop:"+arrayListGeneralStack.pop());
  102. }
  103. System.out.println(arrayListGeneralStack.toString());//打印栈的toString方法
  104. double sum=0;
  105. int size=arrayListGeneralStack.size();
  106. for (int i=0;i<size;i++){
  107. sum+=(double)arrayListGeneralStack.pop();//最后将栈中剩余元素出栈并累加输出。
  108. }
  109. System.out.println("sum="+sum);
  110. System.out.println("interface GeneralStack");
  111. }else if (s.equals("Integer")){ //输入Integer,打印Integer Test。
  112. System.out.println("Integer Test");
  113. int count=sc.nextInt();
  114. int pop_time=sc.nextInt();
  115. ArrayListGeneralStack arrayListGeneralStack = new ArrayListGeneralStack(); //输入Integer,打印Integer Test。
  116. for (int i=0;i<count;i++){ //入栈次数
  117. System.out.println("push:"+arrayListGeneralStack.push(sc.nextInt()));
  118. }
  119. for (int i=0;i<pop_time;i++){//出栈次数
  120. System.out.println("pop:"+arrayListGeneralStack.pop());
  121. }
  122. System.out.println(arrayListGeneralStack.toString()); //打印栈的toString方法。
  123. int sum=0;
  124. int size=arrayListGeneralStack.size();
  125. for (int i=0;i<size;i++){
  126. sum+=(int)arrayListGeneralStack.pop();//最后将栈中剩余元素出栈并累加输出。
  127. }
  128. System.out.println("sum="+sum);
  129. System.out.println("interface GeneralStack");
  130. }else if (s.equals("Car")){//输入Car,打印Car Test
  131. System.out.println("Car Test");
  132. int count=sc.nextInt();
  133. int pop_time=sc.nextInt();
  134. ArrayListGeneralStack arrayListGeneralStack = new ArrayListGeneralStack();//创建可以存放Car类型的ArrayListGeneralStack。
  135. for (int i=0;i<count;i++){
  136. int id=sc.nextInt();
  137. String name=sc.next();
  138. Car car = new Car(id,name);
  139. System.out.println("push:"+arrayListGeneralStack.push(car));
  140. }
  141. for (int i=0;i<pop_time;i++){//出栈次数
  142. System.out.println("pop:"+arrayListGeneralStack.pop());
  143. }
  144. System.out.println(arrayListGeneralStack.toString());
  145. if (arrayListGeneralStack.size()>0){
  146. int size=arrayListGeneralStack.size();
  147. for (int i=0;i<size;i++){
  148. Car car=(Car) arrayListGeneralStack.pop();//将栈中元素出栈,并将其name依次输出。
  149. System.out.println(car.getName());
  150. }
  151. }
  152. System.out.println("interface GeneralStack");
  153. }else if (s.equals("quit")){//如果输入quit,程序直接退出。
  154. break;
  155. }
  156. }
  157.  
  158. }
  159. }

运行结果如下:

 

第三部分:实验总结:

在这周的学习中,我们需要掌握泛型程序的设计。在理论课上我初次了解到泛型程序设计的时候,觉得对泛型的概念还是觉得很抽象,根本不清楚泛型程序设计究竟是如何去实现的。后来又通过上网搜索,自己又对书本上的概念进行了详细的解读,也逐渐对泛型程序设计的大体思路有了一点头绪。

本周的实验内容相较之前的训练新加入了结对编程这个环节。在完成作业的过程中,我与伙伴遇到的最大问题就是编程能力的欠缺。实验课上学长也给我们演示了如何去写出一个完整的java程序,如何按照题目需求去思考问题,去架构程序框架。我们在课后也自己动手做了相应的练习,直观反映出的问题就是基础太薄弱了,应对这个问题我们会在之后的学习中不断练习,争取可以自己写出一个完整的java程序。

201871010131-张兴盼《面向对象程序设计(java)》第十一周学习总结的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  10. 20175227张雪莹 2018-2019-2 《Java程序设计》第十一周学习总结

    20175227张雪莹 2018-2019-2 <Java程序设计>第十一周学习总结 教材学习内容总结 第十三章 Java网络编程 URL类 一个URL对象通常包含最基本的三部分信息:协议 ...

随机推荐

  1. luoguP2824 [HEOI2016/TJOI2016]排序(二分答案做法)

    题意 这题的思路实在巧妙. 首先我们肯定无法对区间进行sort,那么考虑如何使得sort简化. 问:如果给的序列是一个0-1序列,让你区间排序,那么怎么做? 答:建一颗线段树维护sum,求出当前区间中 ...

  2. webapi使用ExceptionFilterAttribute过滤器

    文章 public class ApiExceptionFilterAttribute:ExceptionFilterAttribute { public override void OnExcept ...

  3. LinkCutTree学习笔记

    LinkCutTree 学习笔记 参考来源 https://www.zybuluo.com/xzyxzy/note/1027479 https://www.cnblogs.com/zhoushuyu/ ...

  4. vue-cli2.0和vue-cli3.0中当发布到生产环境时禁用console.log

    vue-cli2.0中的方法 1.安装插件 npm install uglifyjs-webpack-plugin --save-dev 2.修改webpack.prod.conf.js配置文件 co ...

  5. Redis与python

    一.Redis介绍 Redis是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库(非关系型数据库). 本质:将数据保存在内存中. 用途:缓存.消息队列. 1.Redis的特点 R ...

  6. 对mglearn库的理解(转)

    https://blog.csdn.net/az9996/article/details/86490496

  7. [NewLife.XCode]角色权限

    NewLife.XCode是一个有10多年历史的开源数据中间件,支持nfx/netcore,由新生命团队(2002~2019)开发完成并维护至今,以下简称XCode. 整个系列教程会大量结合示例代码和 ...

  8. 在Azure DevOps Server (TFS)的流水线中编译和测试Xcode移动应用(iPhone)

    概述 Xcode是开发基于苹果macOS系统的桌面应用和移动应用的主要IDE工具.使用Azure DevOps Server (原名TFS)系统中的pipelines流水线功能,可以方便的集成Xcod ...

  9. vue中mode hash 和 history的区别

    对于 Vue 这类渐进式前端开发框架,为了构建 SPA(单页面应用),需要引入前端路由系统,这也就是 Vue-Router 存在的意义.前端路由的核心,就在于 —— 改变视图的同时不会向后端发出请求. ...

  10. 02Shell变量

    Shell变量 什么是 shell 变量 shell变量就是 用一个固定的字符串去表示不固定的内容 变量的类型 自定义变量 定义变量 变量名=变量值 (显式赋值) 变量名必须以字母或下划线开头,区分大 ...