zoukankan      html  css  js  c++  java
  • 201871010117石欣钰《面向对象程序设计(java)》第十一周学习总结

    博文正文开头格式:(2分)

    项目

    内容

    这个作业属于哪个课程

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

    这个作业的要求在哪里

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

    作业学习目标

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


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

    (1) 理解泛型概念;

    i. 从java5开始,引入了参数化类型(Parameterized Type)的概念,改造了所有的Java集合,使之都实现泛型,允许程序在创建集合时就可以指定集合元素的类型,比如List<String>就表名这是一个只能存放String类型的List;

    ii. 泛型(Generic):就是指参数化类型,上面的List<String>就是参数化类型,因此就是泛型,而String就是该List<String>泛型的类型参数;

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

     1) 不仅Java的集合都定义成了泛型,用户自己也可以定义任意泛型的类、接口,只要在定义它们时用<>来指定类型参数即可;

        2) 例如:public class Fruit<T> { ... },其中<T>指定了该泛型的类型参数,这个T是一个类型参数名,用户可以任意命名(就像方法参数的形参名一样),只有在定义该泛型的对象时将T替换成指定的具体类型从而产生一个实例化的泛型对象,例如:Fruit<String> fruit = new Fruit<>(...);

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

    定义泛型方法语法格式如下:

          

           调用泛型方法语法格式如下:

     

           说明一下,定义泛型方法时,必须在返回值前边加一个<T>,来声明这是一个泛型方法,持有一个泛型T,然后才可以用泛型T作为方法的返回值。

           Class<T>的作用就是指明泛型的具体类型,而Class<T>类型的变量c,可以用来创建泛型类的对象。

           为什么要用变量c来创建对象呢?既然是泛型方法,就代表着我们不知道具体的类型是什么,也不知道构造方法如何,因此没有办法去new一个对象,但可以利用变量c的newInstance方法去创建对象,也就是利用反射创建对象。

           泛型方法要求的参数是Class<T>类型,而Class.forName()方法的返回值也是Class<T>,因此可以用Class.forName()作为参数。其中,forName()方法中的参数是何种类型,返回的Class<T>就是何种类型。在本例中,forName()方法中传入的是User类的完整路径,因此返回的是Class<User>类型的对象,因此调用泛型方法时,变量c的类型就是Class<User>,因此泛型方法中的泛型T就被指明为User,因此变量obj的类型为User。

           当然,泛型方法不是仅仅可以有一个参数Class<T>,可以根据需要添加其他参数。

           为什么要使用泛型方法呢?因为泛型类要在实例化的时候就指明类型,如果想换一种类型,不得不重新new一次,可能不够灵活;而泛型方法可以在调用的时候指明类型,更加灵活。

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

    1.泛型接口的定义

    public interface IPool <T>
    {
         T get();
         int add(T t);
    }

    例子;

    public interface List<E> {
    void add(E x);
    Iterator<E> iterator();
    ...
    }
    public interface Map<K, V> {
    Set<K> setSet();
    V put(K key, V value);

    2。泛型接口要注意的事项

    A. 接口上自定义泛型的具体数据类型是在实现一个接口的时候指定的。

    B. 如果接口上自定义的泛型,在实现接口的时候没有指定具体的数据类型,就默认为Object类型。

    C. 如果实现一个接口的时候,还不明确目前要操作的数据类型,要等到创建接口实现类对象的时候才去指定泛型的具体数据类型。该怎么实现呢?

    interface Dao<T> {
    public void add(T t);
    }

    public class Demo<T> implements Dao<T> {

    @Override
    public void add(T t) {
    ...
    }

    public static void main(String[] args) {
    Demo<String> d = new Demo<String>();
    }

    }
    总结起来就是,如果要延长接口自定义泛型 的具体数据类型,那么格式如下:

    修饰符 class 类名<声明自定义泛型> implements 接口名<声明自定义泛型> { ... }

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

    在没有泛型之前,当我们将一个对象放进集合中,集合会立刻忘记该对象的类型,它会把所有对象都当作Object类型来处理。所以从集合中取出对象的时候,我们通常需要进行强制类型转换,这种做法不仅造成代码的臃肿,而且容易引起异常。

    在增加了泛型支持后:

    集合可以记住元素的类型,并且在编译的时候检查元素类型,避免引起ClassCastException异常。将运行时的异常提前至了编译时。
    所有的强制转换都是自动和隐式的,提高代码的重用率。
    使代码更加简洁,程序更加健壮。

    第二部分:实验部分

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

    测试程序1:

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

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

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

    程序代码如下:

    PairTets1:

    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
    {
        /**
             * 获取字符串数组的最小值和最大值。.
             * @param a an array of strings
             * @return 一个具有最小值和最大值的对,如果A为空或空,则为null
         */
       public static Pair<String> minmax(String[] a)//用具体的类型替换类型变量可以实例化泛型类型
       {
          if (a == null || a.length == 0return 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];
             if (max.compareTo(a[i]) < 0) max = a[i];
          }
          return new Pair<>(min, max);
       }
    }

    Pair:

    package pair1;
     
    /**
     * @version 1.00 2004-05-10
     * @author Cay Horstmann
     */
    public class Pair<T> //定义了一个泛型类,该类引入了一个类型变量T
    {
       private T first;
       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; }
    }

     程序运行结果如下:

     

    测试程序2:

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

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

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

    程序代码如下:

    PairTest2:

    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);
    System.out.println("min = " + mm.getFirst());
    System.out.println("max = " + mm.getSecond());
    }
    }

    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 values, or null if a is null or empty
    */
    public static <T extends Comparable> Pair<T> minmax(T[] a)
    {
    if (a == null || a.length == 0) return null;
    T min = a[0];
    T max = a[0];
    for (int i = 1; i < a.length; i++)
    {
    if (min.compareTo(a[i]) > 0) min = a[i];
    if (max.compareTo(a[i]) < 0) max = a[i];
    }
    return new Pair<>(min, max);
    }
    }

    Pair:

    package pair2;

    /**
    * @version 1.00 2004-05-10
    * @author Cay Horstmann
    */
    public class Pair<T>
    {
    private T first;
    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; }
    }

    程序运行结果如下:

     

    测试程序3:

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

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

     程序代码如下:

    PairTest3:

    package pair3;
     
    /**
     * @version 1.01 2012-01-26
     * @author Cay Horstmann
     */
    public class PairTest3
    {
       public static void main(String[] args)
       {
          var ceo = new Manager("Gus Greedy"80000020031215);
          var cfo = new Manager("Sid Sneaky"60000020031215);
          var buddies = new Pair<Manager>(ceo, cfo);     
          printBuddies(buddies);
     
          ceo.setBonus(1000000);
          cfo.setBonus(500000);
          Manager[] managers = { ceo, cfo };
     
          var result = new Pair<Employee>();
          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)
       {
          if (a.length == 0return;
          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)
       {
          minmaxBonus(a, result);
          PairAlg.swapHelper(result);// SavaHelp捕获通配符类型
       }
    // 无法写入公共静态<T超级管理器> ...
    }
     
    class PairAlg
    {
       public static boolean hasNulls(Pair<?> p)
       {
          return p.getFirst() == null || p.getSecond() == null;
       }
     
       public static void swap(Pair<?> p) { swapHelper(p); }
     
       public static <T> void swapHelper(Pair<T> p)
       {
          T t = p.getFirst();
          p.setFirst(p.getSecond());
          p.setSecond(t);
       }
    }

    Pair:

    package pair3;
     
    /**
     * @version 1.00 2004-05-10
     * @author Cay Horstmann
     */
    public class Pair<T> //定义了一个泛型类,该类引入了一个类型变量T
    {
       private T first;
       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; }
    }

    Employee:

    package pair3;
     
    import java.time.*;
     
    public class 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.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
       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;
       }
    }

     程序运行结果如下:

     

    实验2结对编程练习,将程序提交到PTA2019面向对象程序设计基础知识测试题(2

    1 编写一个泛型接口GeneralStack要求类方法对任何引用类型数据都适用。GeneralStack接口中方法如下:

    push(item);            //itemnull,则不入栈直接返回null

    pop();                 //出栈,如为栈为空,则返回null

    peek();                //获得栈顶元素,如为空,则返回null.

    public boolean empty();//如为空返回true

    public int size();     //返回栈中元素数量

    2定义GeneralStackArrayListGeneralStack要求:

    ü 类内使用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程序直接退出。否则,输入整数mnm代表入栈个数,n代表出栈个数。然后声明栈变量stack

    ü 输入Integer,打印Integer Test。建立可以存放Integer类型的ArrayListGeneralStack。入栈m次,出栈n次。打印栈的toString方法。最后将栈中剩余元素出栈并累加输出。

    ü 输入Double ,打印Double Test。剩下的与输入Integer一样。

    ü 输入Car,打印Car Test。其他操作与IntegerDouble基本一样。只不过最后将栈中元素出栈,并将其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

     

    代码如下:

    package JavaTest;

    import java.util.ArrayList;
    import java.util.Scanner;

    interface GeneralStack<T>{ //泛型类接口GeneralStack<T>
    public T push(T item); //如果item为null,则不入栈直接返回null。
    public T pop(); //出栈,如为栈为空,则返回null。
    public T peek(); //获得栈顶元素,如为空,则返回null.
    public boolean empty(); //如为空返回true
    public int size(); //返回栈中元素数量
    }
    class ArrayListGeneralStack implements GeneralStack{ //创建一个实现GeneralStack接口的类
    ArrayList l =new ArrayList();
    @Override //重写toString方法
    public String toString() {
    return l.toString();
    }

    @Override //重写压栈方法
    public Object push(Object item) {
    if (l.add(item)){
    return item;
    }else {
    return false;
    }
    }

    @Override //重写出栈方法
    public Object pop() {
    if (l.size()==0){ //判断栈为空时,返回null
    return null;
    }
    return l.remove(l.size()-1);
    }

    @Override //重写获取栈顶元素的函数
    public Object peek() {
    return l.get(l.size()-1);
    }

    @Override
    public boolean empty() { //栈为空时,直接返回boolean值
    if (l.size()==0){
    return true;
    }else {
    return false;
    }
    }

    @Override //重写得到栈中元素个数的函数
    public int size() {
    return l.size();
    }
    }

    class Car{ //定义一个Car类
    private int id; //两个私有属性
    private String name;

    @Override
    public String toString() {
    return "Car [" + "id=" + id + ", name=" + name + ']';
    }

    public int getId() {
    return id;
    }

    public void setId(int id) {
    this.id = id;
    }

    public String getName() {
    return name;
    }

    public void setName(String name) {
    this.name = name;
    }

    public Car(int id, String name) {
    this.id = id;
    this.name = name;
    }
    }
    public class Test {
    public static void main(String[] args) {
    Scanner in =new Scanner(System.in);
    while (true){
    String v = in .nextLine();
    //输入选项,有quit, Integer, Double, Car 4个选项。
    if (v.equals("Double")){ //输入Double ,打印Double Test。 
    System.out.println("Double Test");
    int count=in.nextInt();
    int pop_time=in.nextInt();
    ArrayListGeneralStack arrayListGeneralStack = new ArrayListGeneralStack();//建立可以存放Double类型的ArrayListGeneralStack。
    for (int i=0;i<count;i++){ //入栈次数
    System.out.println("push:"+arrayListGeneralStack.push(in.nextDouble()));
    }
    for (int i=0;i<pop_time;i++){ //出栈次数
    System.out.println("pop:"+arrayListGeneralStack.pop());
    }
    System.out.println(arrayListGeneralStack.toString()); //打印栈的toString方法
    double sum=0;
    int size=arrayListGeneralStack.size();
    for (int i=0;i<size;i++){
    sum+=(double)arrayListGeneralStack.pop(); //最后将栈中剩余元素出栈并累加输出。
    }
    System.out.println("sum="+sum);
    System.out.println("interface GeneralStack");
    }else if (v.equals("Integer")){ //输入Integer,打印Integer Test。
    System.out.println("Integer Test");
    int count=in.nextInt();
    int pop_time=in.nextInt();
    ArrayListGeneralStack arrayListGeneralStack = new ArrayListGeneralStack();//建立可以存放Integer类型的ArrayListGeneralStack。
    for (int i=0;i<count;i++){ //入栈次数
    System.out.println("push:"+arrayListGeneralStack.push(in.nextInt()));
    }
    for (int i=0;i<pop_time;i++){ //出栈次数
    System.out.println("pop:"+arrayListGeneralStack.pop());
    }
    System.out.println(arrayListGeneralStack.toString()); //打印栈的toString方法。
    int sum=0;
    int size=arrayListGeneralStack.size();
    for (int i=0;i<size;i++){
    sum+=(int)arrayListGeneralStack.pop(); //最后将栈中剩余元素出栈并累加输出。
    }
    System.out.println("sum="+sum);
    System.out.println("interface GeneralStack");
    }else if (v.equals("Car")){ //输入Car,打印Car Test。
    System.out.println("Car Test");
    int count=in.nextInt();
    int pop_time=in.nextInt();
    ArrayListGeneralStack arrayListGeneralStack = new ArrayListGeneralStack(); //创建可以存放Car类型的ArrayListGeneralStack。
    for (int i=0;i<count;i++){ //入栈次数
    int id=in.nextInt();
    String name=in.next();
    Car car = new Car(id,name);
    System.out.println("push:"+arrayListGeneralStack.push(car));
    }
    for (int i=0;i<pop_time;i++){ //出栈次数
    System.out.println("pop:"+arrayListGeneralStack.pop());
    }
    System.out.println(arrayListGeneralStack.toString()); //定义toString方法
    if (arrayListGeneralStack.size()>0){ //栈不为空
    int size=arrayListGeneralStack.size();
    for (int i=0;i<size;i++){
    Car car=(Car) arrayListGeneralStack.pop();//将栈中元素出栈,并将其name依次输出。
    System.out.println(car.getName());
    }
    }
    System.out.println("interface GeneralStack");
    }else if (v.equals("quit")){ //如果输入quit,程序直接退出。
    break;
    }
    }
    in.close();
    }

    }

     实验总结;本周学习的内容是java的泛型程序设计技术。泛型是java5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。通过老师的讲解和动手实验,我掌握了泛型类的定义与使用, 了解了泛型方法的声明与使用,但是在结队编程的过程中也遇到了很多问题。在之后的学习中,我们有问题可以一起克服,慢慢去探索未知道路。

  • 相关阅读:
    macbook 无声音解决方案
    webapck dev server代理请求 json截断问题
    百度卫星地图开启
    服务器 nginx配置 防止其他域名绑定自己的服务器
    记一次nginx php配置的心路历程
    遇到npm报错read ECONNRESET怎么办
    运行svn tortoiseSvn cleanup 命令失败的解决办法
    svn add 命令 递归目录下所有文件
    m4出现Please port gnulib freadahead.c to your platform! Look at the definition of fflush, fread, ungetc on your system, then report this to bug-gnulib."
    Ubuntu下安装GCC,mpc、mpfr、gmp
  • 原文地址:https://www.cnblogs.com/sxy19991214/p/11838104.html
Copyright © 2011-2022 走看看