20172314 2017-2018-2 《程序设计与数据结构》第七周学习总结
教材学习内容总结
-
创建子类:
- 继承就是从现有类派生新类的过程,通过在子类的声明头中写
public class 子类名 extends 父类名;
来实现。 - 子类的实例化并不依赖于父类的实例化。
- 继承具有单向性,父类不能引用子类中声明的变量和方法。
- 构造方法不会继承。
- 继承就是从现有类派生新类的过程,通过在子类的声明头中写
-
protected修饰符:
- 父类中的公共方法可以在子类中通过名称访问,若子类想访问其私有方法,那么父类的方法就必须声明为protected可见性,例如
protected int a=12;
- protected可见性提供了允许继承的最大可能的封装性。
- 父类中的公共方法可以在子类中通过名称访问,若子类想访问其私有方法,那么父类的方法就必须声明为protected可见性,例如
-
super引用:
- 用来调用父类的构造方法。
- 子类构造方法时,如引用父类的则例如
public 子类名(int 父类构造方法名,int 子类构造方法名)
- 如果不需要这种调用,Java会自动在构造方法的开始处产生一行super()调用,super引用的操作只能在子类中执行,并且必须是第一行执行(子类构造方法的首行)。
-
多继承:
- 一些面向对象语言允许子类有多个父类。Java中依赖借口实现这一功能。
-
重写方法:
- 在继承中,子类和父类有相同的方法名和签名时,子类方法重写父类方法,子类优先,调用方法的对象决定了哪一个版本的方法将被实际执行(子类不能重写final方法)。例如书上的
parked.message();
dates.message();
,进行不同的操作,产生不同的结果。
- 在继承中,子类和父类有相同的方法名和签名时,子类方法重写父类方法,子类优先,调用方法的对象决定了哪一个版本的方法将被实际执行(子类不能重写final方法)。例如书上的
-
影子变量:
- 在子类中声明一个与父类同名的变量,该变量称为影子变量。这种声明引起混淆,应避免。
-
Object类:
- Java中所有的类都由Object类派生,每一个类都继承toString方法和equals方法。
-
抽象类:
- 抽象类通常含有(不必一定)未被定义的抽象方法,不能被实例化。
- 每个抽象方法都必须使用abstract修饰符。
- 由抽象类派生出的子类必须重写所有父类的抽象方法,否则子类仍然是抽象类。
-
可见性:
- 父类的私有可见性成员会存在于子类当中,但是不能通过成员名直接调用,可以通过调用一个能调用私有成员的方法,间接地调用。
-
继承的限制:
- 在一个方法声明中使用final修饰符,使得该方法在任何派生类中不能被重写。
- final修饰符也可以作用于整个类,使得该类不能用于派生新类。
教材学习中的问题和解决过程
- 问题一:教材中在讲super的引用时,提到如下,而在例9.9中的Advice类却在最后使用了
super.message();
用super引用调用父类构造方法的操作只能在子类中进行,并且必须是在第一行执行。
- 问题一解答:当时在看到例9.9时,对Advice类没有什么疑惑的地方,感觉很正确,可以理解,但是偶然又看到super部分的概念后,想起了这个例子,便对super要放在第一行产生了疑问,在网上查了一下super放第一行执行的原因之后,发现是我理解错误,我误认为只要用到super,就必须把它放在首行。事实上,之所以super要放在第一行,是为了在初始化当前对象之前,先保证父类对象初始化,在网上也找到了相关的问题,特别注意,这是指调用父类的构造方法时,必须在子类的构造方法首行,对于父类的其他方法则没有此要求,他们可以直接继承。而在例9.9中,并没有调用父类的构造方法,只是一个message方法,所以不需要。通过这个不细心的问题,加深了我对super用法的理解。
- 问题二:书上课后题SR9.9的b,“子类可以重写父类的构造方法”,错误的原因。
- 问题二解答:我认为错误的原因是构造方法根本不可以被继承,只能被调用,没有修改的机会。而答案的解释是“构造方法无返回类型,如果试图重写父类的构造方法,将会产生语法错误,因为除了构造方法之外的所有方法必须有返回。”似乎与我的原因没关系...但同时又多了一个理解,鉴于理解的有点模糊,因此又有了第三个问题。
- 问题三:子类调用父类的构造方法的原理。
- 问题三解答:参考一个例子:
说明:如果没有1处的无参数构造方法,那么3处一定要主动调用父类带参数的构造方法。如果有1处的构造方法,那么3处代码可以不要,因为Java会自动默认调用父类的无参数构造方法。记住一点:在构造子类时,一定会调用到父类的构造方法。 所以父类要么有一个默认的无参数构造,这样Java会自动调用这个无参数的构造。如果父类没有无参数的构造,那么就要你自己在子类的构造中,通过super()的方式调用父类的构造。所以说,子类还是不能继承父类的构造方法,但是可以调用。class A{ public A(){} // 1:无参数构造方法。 public A(String s){} // 2. } class B extends A{ public B(String s){ super(s); // 3. } }
- 问题四:为什么子类不能继承父类的构造方法?
- 问题四解答:关于构造方法,每个类中都有属于自己的构造方法,即使你没有声明,但是java虚拟机也帮你建了一个隐式的构造方法,因此子类也一定会有自己的构造方法,所以没有必要去继承父类的构造方法,同时,父类构造方法用来构建父类的对象,子类的对象需要声明自己的构造对象来创建,所以更不需要继承。
- 问题五:抽象类到底是一个什么样的存在?
- 问题五解答:在查阅相关资料后,找到了一个最容易理解的解释。如下,所以说抽象类可看做一个统筹的类,并不能被实例化,所以称作抽象类。参考如何生动的解释为什么java中要用抽象类?
你定义一个动物类,继承一个狗类一个猫类。你可以new一个狗类的实例,但你不能new一个动物的实例,因为不存在这样一个不属于任何子类的动物类实例。所以,动物类必须是抽象的。
代码调试中的问题和解决过程
-
问题一:在IDEA中运行代码时,总有红色波浪线提示错误,但目测被标注的地方没有哪里写错了。
-
问题一解决:这是在开始使用IDEA时遇到的问题,后来发现是少加了一个“}”,在后来的使用中,差不多知道了IDEA的特点,有时候它提示的错误的地方并不一定就是那里出问题了。
-
问题二:这次在用虚拟机push的时候遇到了两次错误。
-
问题二解决:第一个错误是因为之前push的时候没有进行完,有残留,所以再次push新的时候,出现两次不同的提交,最后我把那几个删掉之后就可以了。第二个错误在网上查找了类似的问题其中提到的解决办法如下,其实跟之前的push失败一样用
git pull origin master
和git push origin master
但错误的原因描述不一样。git由于不经常提交代码所以会出现版本更新的问题
git pull(已经绑定默认远程仓库的情况)
或者:
git pull origin master
这个时候git命令行中分枝状态变成了 master | MERGING,现在:
git add .
git commint -m "merge with remote"
最后git push origin master -
问题三:在输出一长段内容时,想使用“\t”来分隔,但错误如图
-
问题三解决:在IDEA中这样输出就是正确的,助教说可能是虚拟机有问题。在查找解决办法的过程中了解到java里的\t是补全当前字符串长度到8的整数倍,最少1个最多8个空格。补多少要看你\t前字符串长度,比如当前字符串长度10,那么\t后长度是16,也就是补6个空格,如果当前字符串长度12,此时\t后长度是16,补4个空格。对于我的问题,没有找到合适的解决办法,就在虚拟机中把“\t”换成了空格。输出来的效果一样。
-
问题四:代码如图,希望输出的per为120000/5,即为24000,但输出总是0。
-
问题四解决:尝试了加括号,但没有用,最后的解决方法是把per去掉,直接在println输出时加上“pages/pictrue”。之后询问了助教,他指出应该定义一个per方法,如图,并在最后的测试类中通过
book.pages()
来调用该方法才对,原因是在实例化Book对象时,那个对象并没有使用Book类中出构造方法以外的方法,所以需要使用额外添加的方法才可以。
代码托管
上周考试错题总结
-
错题一:
-
错题一解析:在Java中,数组是对象。我在做这道题时,首先确定数组是对象,但不知道他是不是原始数据类型。但看到选项D觉得很有道理,就被他成功说服了。实际上,变量是存储整个数组的内存块的引用变量,而数组不是变量。
-
错题二:
-
错题二解析:首先是产生了1000个参考变量,每个都是一个BankAccount对象,而在察看了条目的解释后,还是不理解条目是指什么。在这个解释中,应该是指变量吧。参考Java流里的条目名称是什么?emmmmm...无法理解。
-
错题三:
-
错题三解析:第一个中a、b都是数组,我觉得可以理解为String a,b这类的吧。但是在数组的声明中int a[ ]与int [ ] a是等价的呀。而我当时选是因为觉得最正确的写法是a的,所以选了一个,int[]之后的,就是数组,而int c ,d[]; c是一个整型变量,d才是数组。
-
错题四:
-
错题四解析:“=”是一个赋值运算符,在a=b后,由于ab都是数组,就产生了一个别名,如果其中一个是确定的数,就把他赋值给另一个。
-
错题五:
-
错题五解析:我在做这道题时,认为不必提供参数是以为在测试代码中不需要确定参数,而实际上主方法需要参数,以防程序员希望允许用户提供命令行参数。在java命令之后,在命令行输入的任何内容都将被接受为命令行参数。
-
错题六:
-
错题六解析:这道题审题不仔细,没有看到是“cannot”,以为他说的是“can”...
-
错题七:
-
错题七解析:做题的时候忘记了还有可变长度参数列表这种东西,可变长度参数列表通过使用省略号(…)用于指定可变的长度。
-
错题八:
-
错题八解析:当对ArrayList的前部分进行插入或删除时,就会发生大量的元素复制,从而降低其效率。这里插入或删除时,并不仅仅改变一个元素,后面的都要改变,这一点是要特别注意的。
结对及互评
点评:
-
博客中值得学习的或问题:谭鑫在代码调试的问题中,详细记录了在编写PP9.3时的过程,还附有UML图,可以说是非常用心了,向优秀大学生低头。王禹涵的博客整体比较简单,部分地方没有写完,建议写得详细一点,充实自己的博客。
-
代码中值得学习的或问题:谭鑫对代码有清晰的认识,构思严密,掌握的很好,我所欠缺的就是一个清晰地脑回路。王禹涵的代码托管打不开,显示访问的资源不存在。
-
基于评分标准,我给谭鑫的博客打分:13分。得分情况如下:
- 正确使用markdown语法(1分)。
- 模板要素齐全(1分)。
- 问题加分(6分)。
- 代码量(1分)。
- 排版精美加1分
- 代码规范加1分
- 有动手写新代码的加1分
- 代码Commit Message规范的加1分
-
基于评分标准,我给王禹涵的博客打分:10分。得分情况如下:
- 有动手写新代码的加1分。
- 问题加分(6分)。
- 有动手写新代码的加1分 。
- 正确使用markdown语法(1分)。
- 模板要素齐全(1分)。
点评过的同学博客和代码
其他
这周主要学习了继承,这就涉及到类的编写,由于我对第七章编写类的掌握不是很全面,所以这周的学习提高了我编写类的能力,对一个类的的认识更加全面,还有就是对这周的实验作业有点一知半解,没有细致的理解。
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | |
---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 |
第一周 | 93/93 | 1/1 | 20/20 |
第二周 | 305/398 | 1/2 | 20/38 |
第三周 | 328/651 | 2/4 | 25/60 |
第四周 | 1013/1689 | 1/5 | 30/90 |
第五周 | 795/2407 | 1/6 | 30/120 |
第六周 | 1117/2921 | 1/7 | 30/150 |
第七周 | 703/3511 | 1/8 | 40/190 |