20172302 《程序设计与数据结构》第八周学习总结


2018年学习总结博客总目录:第一周 第二周 第三周 第四周 第五周 第六周 第七周 第八周


教材学习内容总结

1.绑定(binding)与后绑定(动态绑定):我们在程序执行时可能会要求某段代码来完成一个方法的调用,这被称为一个方法调用与一个方法定义的绑定。大多数情况下,这种绑定是在编译阶段就会完成。但是对于多态性引用,这种绑定会延迟到程序运行时才会完成,并且要绑定的方法定义取决于当时引用变量所引用的对象,这就是后绑定,或称为动态绑定。

2.后绑定的效率要低于编译阶段的绑定效率,因其需要在程序执行期间去进行判断,从而绑定与引用变量所引用的对象相对应的方法。

3.由继承实现多态性:当用类名声明一个引用变量时,这个变量可以指向该类的任何一个对象,同时,它也能引用通过继承与它所声明的类型有关的任何类的对象。下面这是一个小例子,我们可以看到Christmas是Holiday的一个子类,通过这样的声明,我们的day变量就是可以调用Christmas中的方法,即实际将调用的方法取决于对象的类型而不是引用变量的类型。同时多态机制允许用具有一致性但又特殊的方式处理类似的对象。

4.利用接口实现多态性:首先一个接口名可以用来声明对象引用变量,一个接口引用变量可以指向任何实现该接口的类的对象。执行代码时实际调用的方法将取决于调用发生时接口引用所指向的对象的类型。使用接口引用变量时,只能调用定义在接口中的方法,即使接口引用变量所指向的对象还有一些其他可用方法,也不能调用。举一个接口实现多态的小例子:(如下面中Philosopher和Dog都实现了Speaker接口)

public interface Speaker
{
    public void speak()
     public void announce(String str)
}

class test
{
   public static void main(String[] args){
   Speaker current;
   current = new Philosopher();
   currrent.speak();
    currrent = new Dog();
    current.speak();
}
 

如果Dog类没有announce方法,那么我们引用变量指向Dog时将不能调用announce方法,如果需要,可以将其转换为Philosopher的类型((Philosopher)current).announce;

5.排序:这里分析两种:选择排序法和插入排序法。
选择排序的基本思想:第1趟,在待排序记录r[1]~r[n]中选出最小的记录,将它与r[1]交换;第2趟,在待排序记录r[2]~r[n]中选出最小的记录,将它与r[2]交换;以此类推,第i趟在待排序记录r[i]~r[n]中选出最小的记录,将它与r[i]交换,使有序序列不断增长直到全部排序完毕。

初始序列:{49 27 65 97 76 12 38}
第1趟:12与49交换:12{27 65 97 76 49 38}
第2趟:27不动 :12 27{65 97 76 49 38}
第3趟:65与38交换:12 27 38{97 76 49 65}
第4趟:97与49交换:12 27 38 49{76 97 65}
第5趟:76与65交换:12 27 38 49 65{97 76}
第6趟:97与76交换:12 27 38 49 65 76 97 完成

插入排序法:检查第i个数字,如果在它的左边的数字比它大,进行交换,这个动作一直继续下去,直到这个数字的左边数字比它还要小,就会停止,进行下一个数字的排序,直到形成有序数列。

1 5 7 3 1 6
把表分成两部分,前半部分已排序,后半部分未排序,我用|分开
初始为 5 | 1 7 3 1 6
一次插入排序,把第一个1插入前边已排序部分,得
1 5 | 7 3 1 6
后边依次是
1 5 7 | 3 1 6
1 3 5 7 | 1 6
1 1 3 5 7 | 6
1 1 3 5 6 7 |

扫描二维码关注公众号,回复: 99416 查看本文章

6.排序算法比较:选择排序和插入排序实际上进行的比较次数相近,都是大约进行n^2次比较,但是选择排序法所执行的交换操作的次数要少,因此选择排序法要优于插入法。

7.搜索:分析两种:线性搜索和二分搜索。
线性搜索,即从搜索池的起点开始,将目标依次与每个元素进行比较,最终找到目标元素,或搜索到数列的终点后发现数列中不存在目标元素。这里列一下代码的编写:

{
      int index = 0;
      boolean found = false;

      while (!found && index < list.length)
      {
         if (list[index].equals(target))
            found = true;
         else
            index++;
      }

      if (found)
         return list[index];
      else
         return null;
   }

二分搜索:前提是数列必须是已经排序好的,搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组为空,则代表找不到。下面是其代码(以升序的数列为例)

int min=0, max=list.length, mid=0;
      boolean found = false;

      while (!found && min <= max)
      {
         mid = (min+max) / 2;
         if (list[mid].equals(target))
            found = true;
         else
            if (target.compareTo(list[mid]) < 0)
               max = mid-1;
            else
               min = mid+1;

教材学习中的问题和解决过程

  • 问题1:关于上面所提到的“实际将调用的方法取决于对象的类型而不是引用变量的类型”,以及书上例题中的这个staffList[0] = new Executive("Sam", "123 Main Line", "555-0469", "123-45-6789", 2423.07);,((Executive)staffList[0]).awardBonus(500.00);,我就不明白这个引用变量和对象的含义了。

  • 问题1解决方案:通过查资料,算是明白一些,这里尝试说一下:先拿最简单的来说,Animal animal1 = new Animal();这条语句我们将它拆分为两句Animal animal1;animal1 = new Animal();第一条语句做的是创建了一个引用变量animal,在第二条语句执行时,这个引用变量指向了Animal这个对象。
    然后再去理解我们的多态这里的引用变量和对象的关系(Cat为Animal的一个子类):Animal animal2 = new Cat();同样拆为两句,Animal animal2;animal2 = new Cat();,这时理解起来就很简单,我们创建了一个Animal的引用变量animal2,然后这个引用变量是指向Animal的子类Cat类的对象的,那么引用变量的类型是Animal,而引用的对象的类型是Cat。这也就解释了多态使用中的具体含义。参考链接:(https://www.cnblogs.com/hukai46/p/5258668.html)

  • 问题2:一个小问题:【例10.10】中的equals方法,我以为是下面的CompareTo方法调用了这个方法,可又感觉不对,不是一个类型的怎么使用的?

  • 问题2解决方案:后来上去问了老师,老师说CompareTo方法中使用的是String类里面的equals方法,和上面的没有关系。我就开始找这个方法到底在哪使用了?我读完整个代码,包括下一节的都没有发现这个方法的作用,完全没有使用这个方法,还有第10.5.1的最后一段说是调用了equals方法,完全看不到,很迷糊,这哪里使用了?上面问题解决了,但这个方法在哪使用没有解决。

  • 问题3:关于这个后绑定,是否是只有多态情况下才会进行后绑定,其它情况下的绑定是否都在编译阶段已经完成?

  • 问题3解决方案:这个查了一些资料,见下图,这样的情况下即使不是多态也有可能进行后绑定,后绑定运用会去判断与它最符合的声明类型和方法名。

代码调试中的问题和解决过程

  • 问题1:关于编程项目PP10.1的编写,一开始想的是只能在这里实现使用接口,不能再去使用使用继承,就是把StaffMember改写为Payable接口,其他的类都声明这个接口实现多态,可做起来就比较吃力。

  • 问题1解决方案:做起来时的想法是将StaffMember类改写为一个接口,然后呢,将Employee类也改为一个接口,为StaffMember接口的一个接口,这样也不符合题目的要求,题目要求的是只去写这一个Payable接口,然后就是一直在改动,最后做的结果是只写了这一个接口,然后让Volunteer类和Employee类都声明该接口,并重写其方法,然后Executive和Hourly类都是继承Employee类,并将Staff类声明该接口,重写方法,Firm为驱动类,完成了通过接口实现多态这一题目。下面是Payable接口的代码:

    public interface Payable
    {
    public String toString();
    public  double pay();
    }
  • 问题2:编程项目PP10.5,这里编写时遇到了一些问题,自己做的时候总是在想着那个DVDCollection类到底该怎么去改写,一直是出现问题。然后导致Movies和Sorting类导致矛盾,两边要求改写的错误恰巧是相矛盾的。

  • 问题2解决方案:最后是参考那个书上的例题,我就没有再使用DVDCollection类,而是直接一个DVD类和一个Movies类,直接是Movies声明那个Comparable接口,然后重写CompareTo方法,再对Movies类进行改写,实例化一个DVD对象的数组,往其中添加元素,再使用Sorting类进行排序,完成这个题目,Movies代码见下:

    public class Movies
    {
    public static void main(String[] args)
    {
        DVD[] movies=  new DVD[7];
    
        movies[0]=new DVD("The Godfather", "Francis Ford Coppola", 1972,24.95,true);
        movies[1]=new DVD("District 9", "Neill Blomkamp", 2009,19.95,false);
        movies[2]=new DVD("Iron Man","Jon Favreau", 2008,15.95,false);
        movies[3]=new DVD("All About Eve", "Joseph Mankiewicz", 1950,17.50,false);
        movies[4]=new DVD("The Matrix", "Andy & Lana Wachowski", 1999,19.95,true);
        movies[5]=new DVD("Iron Man 2","Jon Favreau", 2010,22.99,false);
        movies[6]=new DVD("Casablanca","Michael Curtiz", 1942,19.95,false);
    
        Sorting.selectionSort(movies);
        for(DVD movie:movies)
            System.out.println(movie);
    
        Sorting2.selectionSort(movies);
        for(DVD movie:movies)
            System.out.println(movie);
        }
    }

最后的运行结果:

代码托管

上周考试错题总结

  • 1.Inheritance through an extended (derived) class supports which of the following concepts?
    A . interfaces
    B . modulary
    C . information hiding
    D . code reuse
    E . correctness

  • 解析:当继承一个已有类时,新类不必重新实现任何继承的方法或实例数据,从而为程序员节省了一项工作,提高了效率。因此,代码重用是一种重用其他人的代码的能力,它可以为我们的需要扩展它。

    Java继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。这种技术使得复用以前的代码非常容易,能够大大缩短开发周期,降低开发费用。

  • 2.Which of the following is an example of multiple inheritance?
    A . A computer can be a mainframe or a PC
    B . A PC can be a desktop or a laptop
    C . A laptop is both a PC and a portable device
    D . A portable device is a lightweight device
    E . Macintosh and IBM PC are both types of PCs

  • 解析:多继承意味着一个新的派生类继承了不止一个父类。在上面列出的那些电脑中,一台笔记本电脑从个人电脑和便携设备上继承了一些属性,因此这属于多继承。A、B和E的答案都是单继承的例子,其中一个类至少有两个子类(在A中,计算机有主机和PC机;在B中,PC机有桌面和笔记本电脑,在E,PC机有Macintosh机和IBM 个人计算机),D表示一个类的一个属性。当时误选D项,以为成其他都是属于多继承。

  • 3.A variable declared to be of one class can later reference an extended class of that class. This variable is known as
    A . protected
    B . derivable
    C . cloneable
    D . polymorphic
    E . none of the above, a variable declared to be of one class can never reference any other type of class, even an extended class

  • 解析:一个被声明为一个类的对象可以引用该类的子类,这种方法是被称作为多态,这是在第十章中的内容,一个父类的对象是可以指向任何一个子类的一个对象,这种就是由多态所引起的。

    多态是同一个行为具有多个不同表现形式或形态的能力。多态下允许将子类类型的指针赋值给父类类型的指针。

  • 4.In order to determine the type that a polymorphic variable refers to, the decision is made
    A . by the programmer at the time the program is written
    B . by the compiler at compile time
    C . by the operating system when the program is loaded into memory
    D . by the Java run-time environment at run time
    E . by the user at run time

  • 解析:这道题目是在问是在什么阶段确定多态变量所引用的类型,这也是属于第十章内容。对于多数情况下的这种请求,这种绑定是发生在编译阶段,但是对于多态性引用,这种绑定要延迟到程序运行才能执行,并且要绑定的方法取决于当时引用变量所引用的对象,这种被延迟的请求事件被称为后绑定或动态绑定。

  • 5.Why shouldn't an abstract method be declared final?
    A . There's nothing wrong with doing so
    B . Abstract methods cannot be overridden and they must be if a concrete class ever is to be instantiated
    C . So long as the Abstract method never actually is used in by any other method, there's no problem with doing this
    D . So long as the Abstract method is declared in a Class (not an Interface), there's nothing wrong with doing this
    E . None of the above

  • 解析:为了让抽象方法成为具体的方法,它必须被重写。声明一个方法是final的,这使得它不能被重写,因此无法为一个抽象final方法提供定义。

  • 6.Using the reserved word, super, one can
    A . access a parent class'constructor(s)
    B . access a parent class'methods and instance data
    C . access a child class'constructor(s)
    D . access a child class'methods and instance data
    E . both A and B

  • 解析:这道题目误选A,答案应该是E,使用super的方法是可以访问父类的构造函数、方法以及实例数据,见上周博客有详细介绍,这里是因为题目有错,误选了a。参考链接:(https://www.cnblogs.com/hasse/p/5023392.html)

  • 7.If class AParentClass has a protected instance data x, and AChildClass is a derived class of AParentClass, then AChildClass can access x but can not redefine x to be a different type.
    A . true
    B . false

  • 解析:子类是可以访问父类的任何实例数据或方法的,同时子类也可以重新定义父类中的任何实例数据或方法的,重新定义的父类实例数据称为影子变量,这个我们不提倡,但重写父类的方法这个是经常会使用到的,也是符合规范的。

结对及互评

点评过的同学博客和代码

  • 本周结对学习情况
    • 20172308
    • 博客中值得学习的或问题:

    • 结对学习内容

其他(感悟、思考等)

感悟

  • 这周进行了多态的学习,课本上的这一章第一次读了一遍之后,印象很模糊,而且很多地方都不太明白,又去读了第二遍,才理解了书上的内容包括例题代码的编写,这一章的编程项目做起来难度不算太大,主要就是对前面的一些题目进行修改,完成的比较快,因为这周也在做结对编程的那个四则运算,时间有些不太够用,可能有些东西自己去想的时间不如之前的多,尽量克服一下,下周继续。

学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 5000行 30篇 400小时
第一周 157/157 1/1 15/15
第二周 382/539 1/2 16/31
第三周 317/856 2/4 15/46
第四周 996/1852 1/5 24/70
第五周 578/2330 1/6 16/86 这周对上周第七章的学习有了更深的理解
第六周 475/2805 1/7 14/100 学习了数组方面的相关知识
第七周 629/3434 1/8 14/114 关于继承有一定认识
第八周 1567/5001 3/11 20/134

参考资料

猜你喜欢

转载自www.cnblogs.com/hzy0628/p/8940111.html