20182316胡泊 2019-2020-1 《数据结构与面向对象程序设计》第6周学习总结
教材学习内容总结
第九章:多态
多态
- 定义:同一个变量,在不同时刻可以有不同的类型,这种性质叫做多态。
- 实现:一般通过继承实现,即具有多态性质的变量,只能是可相容的变量类型,而父类与子类恰好满足这个条件。(is-a)
接口
- 定义:接口是一组抽象方法,只有方法名,没有方法体,因此不能被实例化。
- 实现:通过implements来实现接口,且必须提供接口所有方法的定义,否则会报错。(子类除了接口的方法,还可以有自己的方法)
- 多个类可以实现同一个接口,一个类可以实现多个接口(此时,用,隔开各个接口)
- 继承可适用于接口,即一个接口可以派生另一个接口
- 不同点:类的继承可能会有变量保护或者私有无法访问的情况,而接口都是公有的。
- Comparable接口
- 其中只包含了一个compareTo方法,当obj1小于obj2则返回负值,等于返回0,大于则返回正值(整数),而至于如何比较则为自己定义。
if(obj1.compareTo(obj2)<0) System.out.println("1 is less than 2");
public int compareTo(Object o) { Task t1=(Task)o; if(this.task.charAt(0)==t1.task.charAt(0)) return 0; else if(this.task.charAt(0)
- Iterator接口
- 基本方法:hasNext和next,hasNext返回一个boolean型,有下一项则为真,next则直接返回下一项
- 接口引用可以指向任意实现这个接口的对象。
第十章:异常
- 常见异常类型
- 处理异常的方法:
- 不处理异常
- 在异常发生的地方处理
- 在程序的其他地方处理
- 异常处理的作用:当程序中出现暂时无法解决的问题时,如果不管他就会让程序结束在这个异常处,下面的语句永远都不会执行,因此想要使程序遍及每一行代码,就要处理异常。
- try-catch语句
- 一个try可以有几个catch与之相对应,每个catch称为一个异常处理器,当执行了try中的语句后未发生异常,则执行catch之后的语句,如果发生了异常,则找到对应的异常处理器(前提是有),然后在执行catch后的语句。
- finally子句
- 无论以何种方式退出try块,都要执行这个语句,有异常发生时,总是先执行catch语句,再转向finally语句。
- 异常传播:如果在异常发生的地方没有捕获他,那么就转向调用他的方法,以此类推
教材学习中的问题和解决过程
- 问题1.如果没有捕获异常会发生什么?
- 如果抛出的语句没有被立即捕获,那么就会沿着方法链向上传播,期间任何合适的catch都可将其捕获,如果传出了main方法,那么就会导致程序中断。
- 问题2:什么是异常抛出,从哪抛到哪?
- 问题2解决方案:在方法名的后面加上throws Exception的方法来抛出,即不处理异常,将异常抛出,当该方法被调用时,谁调用,谁来处理异常。
- 例如:
import java.util.Scanner;
public class 异常测试 {
public static double yichang() throws Exception { //在方法名的后面加throws Exception,声明即便出错了也继续执行,由调用这个方法的函数来try
System.out.println("请输入一个非零数字");
Scanner sc=new Scanner(System.in);
String a=sc.nextLine();
int shu=Integer.parseInt(a);
double jg=100/shu;
return jg;
}
public static void main(String[] args) {
try{
double c=yichang(); //调用方法,如果没有异常,直接输出,如果有异常则走catch
System.out.println(c);
}
catch(Exception e){
System.out.println("输入不正确");
}
}
}
- 问题3:throws和throw的区别?
- 问题3解决方案:书上没有详细提到throw子句,综合网络的信息,我找到了一个详细的解答
- 1、throws出现在方法函数头;而throw出现在函数体。
- 2、throws表示出现异常的一种可能性,并不一定会发生这些异常;throw则是抛出了异常,执行throw则一定抛出了某种异常对象。
- 3、两者都是消极处理异常的方式(这里的消极并不是说这种方式不好),只是抛出或者可能抛出异常,但是不会由函数去处理异常,真正的处理异常由函数的上层调用处理。
代码调试中的问题和解决过程
- 问题1解决方法:
- “==” 比较的是两个引用在内存中指向的是不是同一对象(即同一内存空间),也就是说在内存空间中的存储位置是否一致。
- equals方法是由Object类提供的,可以由子类来进行重写
Object类默认的实现如下:
1 public boolean equals(Object obj) {
2
3 return (this == obj);
4
5 }
//默认的实现只有当对象和自身进行比较时才会返回true, 这个时候和 “==”是等价的。
Java中很多类(String类 Date类 File类)等都对equals方法进行了重写,常见的String类举例。
1 public class Test {
2 public static void main(String[] args) {
3 String str1 = "abc";
4 String str2 = "abc";
5 System.out.println(str1==str2);//true
6
7
8 String str3 = new String("abc");
9 String str4 = new String ("abc");
10 System.out.println(str3==str4);//false
11 System.out.println(str3.equals(str4));//true
12 }
13 }
分析原因:
先看第3行代码,先在栈中创建一个对 String类的对象引用变量str1,然后通过引用去字符串常量池 里找有没有"abc",如果没有,则将"abc"存放进字符串常量池。这里常量池中并没有“abc”。即在编译期已经创建好(直接用双引号定义的)“abc”,存储在了常量池中。
第4行代码又创建了对String类的对象引用str2,如果已经有”abc” 则直接令str2指向“abc”。这里我们在第三行代码中已经将“abc”这个字符串存储进了常量池。所以str2和str1指向的是同一个“abc”,返回true。
第8行和第9行代码分别创建了2个对象,str3和str4指向的是不同的对象,即上面所说的内存空间中存储位置不同,即常量池中没有对应的“abc”。故str3 == str4返回的肯定是false。
第11行代码 str3.equals(str4) 返回true
因为String类重写了equals方法,比较的是内存空间存放的数据是否相同。这里存放的都是字符串“abc” 故返回true。
总结:
Java 语言里的 equals方法其实是交给开发者去覆写的,让开发者自己去定义满足什么条件的两个Object是equal的。
所以我们不能单纯的说equals到底比较的是什么。你想知道一个类的equals方法是什么意思就是要去看定义。
如果两个对象的引用相同时(指向同一对象时),“==”操作符返回true,否则返回flase。
问题2解决方法:在利用字符串长度来作为循环判断条件时,总是想当然的犯了下标的错误,比如,字符串最后一位的下标应该是length-1,因此如果按照我之前的做法,当循环运行到第一位时,下标就等于length,因此就发了地址越界。
代码托管
上周考试错题总结
- 错题1:We compare sorting algorithms by examining
A . the number of instructions executed by the sorting algorithm
B . the number of instructions in the algorithm itself (its length)
C . the types of loops used in the sorting algorithm
D . the amount of memory space required by the algorithm
E . whether the resulting array is completely sorted or only partially sorted - 解析:不同的排序算法在执行时需要不同数量的指令。
例如,选择排序通常需要比插入排序更多的指令。
因此,我们将排序算法与每个执行来排序数组的指令的数量进行比较。
如果两个排序算法需要大致相同数量的指令来排序一个数组,那么我们也可以检查所需的内存空间。 - 错题2:Polymorphism is achieved by
A . overloading(重载)
B . overriding(重写)
C . embedding(嵌入)
D . abstraction(抽象)
E . encapsulation(封装) - 解析:Java的方法重载,就是在类中可以创建多个方法,它们具有相同的名字,但具有不同的参数和不同的定义。调用方法时通过传递给它们的不同参数个数和参数类型来决定具体使用哪个方法。
在Java中,子类可继承父类中的方法,而不需要重新编写相同的方法。但有时子类并不想原封不动地继承父类的方法,而是想作一定的修改,这就需要采用方法的重写。重写提供了多态性,因为适当的方法是根据当前被引用的对象而调用的。
嵌入是类中包含的类。抽象与多态没有任何关系。封装是使用可见性修饰符(public、private、protected)实现的。 - 错题3:Comparing the amount of memory required by selection sort and insertion sort, what can one say?
A . Selection sort requires more additional memory than insertion sort
B . Insertion sort requires more additional memory than selection sort
C . Both methods require about as much additional memory as the data they are sorting
D . Neither method requires additional memory
E . None of the above - 解析:选择排序和插入排序都不需要额外的内存。
- 错题4:Which of the following statements is completely true?
A . If a class is declared to be abstract then every method in the class is abstract and must be overridden
B . If a class is declared to be abstract then some methods in the class may have their bodies omitted
C . If a class is declared to be abstract then all methods in the class must have their bodies omitted
D . If a class is declared to be abstract then all the instance variables must be overridden when a concrete class is derived from the abstract base class - 解析:创建抽象类的惟一方法是在类中创建一些抽象方法。所以,答案B是正确的。当然,抽象类中的所有方法都不必是抽象的。
- 错题5:Can a program exhibit polymorphism if it only implements early binding?
A . Yes, because one form of polymorphism is overloading
B . No, because without late binding polymorphism cannot be supported
C . Yes, because so long as the programs uses inheritance and/or interfaces it supports polymorphism
D . Yes, because early binding has nothing to do with polymorphism
E . none of the above - 解析:虽然继承和接口支持多态,但只有在有后绑定时才会这样做。但是,重载是多态性的一种形式,只要程序使用重载,多态就在使用中。
- 错题6:What is the efficiency of binary search?
A . n^2
B . n
C . log2 n
D . n/2
E . none of the above - 解析:每次二分搜索消除大约一半的剩余数据。这个过程一直持续到找到需要的元素,或者直到所有可能的数据被消除。因为有n个数据元素,所以在数据量小于一个元素之前,可以将数据减半的次数是log2n。
- 错题7:Binary search can be used on unsorted data it will just perform more slowly.
A . true
B . false - 解析:二分搜索只能在有序的数组元素中进行。
结对及互评
- 博客中值得学习的或问题:
- 对上周的错题进行了仔细的更正和课后复习,我对上周考试题的复习较为草率。
- 博客撰写详细,有理有据。
- 在撰写博客的过程中可以加入更多自己的理解。
- 代码中值得学习的或问题:
- 代码风格良好,便于阅读。
- 基于评分标准,我给本博客打分:13分。得分情况如下:
- 正确使用Markdown语法(加1分):
- 不使用Markdown不加分
- 有语法错误的不加分(链接打不开,表格不对,列表不正确...)
- 排版混乱的不加分
- 模板中的要素齐全(加1分)
- 缺少“教材学习中的问题和解决过程”的不加分
- 缺少“代码调试中的问题和解决过程”的不加分
- 代码托管不能打开的不加分
- 缺少“结对及互评”的不能打开的不加分
- 缺少“上周考试错题总结”的不能加分
- 缺少“进度条”的不能加分
- 缺少“参考资料”的不能加分
教材学习中的问题和解决过程(3分)
代码调试中的问题和解决过程(3分)
本周有效代码超过300分行的(加0分)
- 其他加分:
- 周五前发博客的加1分
- 感想,体会不假大空的加1分
- 进度条中记录学习时间与改进情况的加1分
- 有动手写新代码的加1分
- 错题学习深入的加1分
- 点评认真,能指出博客和代码中的问题的加1分
- 结对学习情况真实可信的加1分
点评过的同学博客和代码
- 本周结对学习情况
- 结对同学学号2332
结对照片
结对学习内容
对上周及本周的考试内容进行了探讨,并通过上网查询等方式深入分析,直到将问题理解。
一起制作博客,markdown,遇到问题相互询问,并解决。
其他(感悟、思考等,可选)
- 程序的错误有时就是很细小,但是如果找不到,就会白费大量时间在没用的地方,反复检查,但如果静下来,跳出程序,整体一步步分析,才能更快发现问题(留下心酸的泪水)。
- 有些看似理所当然的事情,但是当你遇到问题时,才会发现其中细微的不同。
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 10000行 | |||
第一周 | 119/119 | 3/3 | 20/20 | |
第二周 | 302/300 | |||
第三周 | 780/800 | |||
第四周 | 1500/1300 | |||
第五周 | 3068/2500 | |||
第六周 | 4261/4000 |
计划学习时间:30小时
实际学习时间:25小时
参考资料
- 《Java程序设计与数据结构教程(第二版)》