20172311 2017-2018-2 《程序设计与数据结构》第七周学习总结
教材学习内容总结
本周主要学习了继承的相关知识:
1.继承在父类和子类之间建立了一种“是”关系,即子类是一种更具体的父类版本
2.继承具有单向性
3.父类的私有方法或变量不能在子类中访问
4.protected可见性提供了允许继承的最大可能的封装性。
5.使用super引用可以调用父类的构造方法,用super引用调用父类构造方法的操作只能在子类中执行,且必须在第一行执行,super引用也可以引用父类的其他变量和方法。
6.Java语言设计者明确决定不支持多继承。可以依靠接口提供多继承的最好特性而不增加歧义。
7.可以用final修饰符定义一个方法,子类将不能重写final方法。这种技术用于保证子类必须使用的一个特定方法。
8.在类层次结构中,应当合理地将类的公共特征保持在尽可能高的类层次级上,从而最大化复用现有类的可能性,有助于软件的维护。
9.继承机制具有传递性。
10.所有的Java类都直接或间接地由Object类派生,Java程序的每一个类都继承toString方法和equals方法。重写Object类的toString方法和equals方法一般是为了满足用户自己的需求。
11.抽象类的引入。
12.类的继承和接口的继承不能重叠,即接口不能用于派生新类,类不能用于派生接口,仅当一个类设计为实现一个接口时,这个实现类和接口之间才有交互。
13.父类的私有成员也被子类继承,虽然不能以成员名直接访问,但是可以间接的访问。
教材学习中的问题和解决过程
- 问题1:对课本中Java中依赖接口提供多继承的最好特性理解模糊
- 问题1解决方案:通过查阅资料了解到继承多个接口的大致方法为:
package com.lib.ThinkInJava.mutilExtends;
public interface Lethal {
void kill();
}
package com.lib.ThinkInJava.mutilExtends;
public interface Monster {
void destroy();
}
package com.lib.ThinkInJava.mutilExtends;
public interface Vampire extends Monster, Lethal {
void drinkBlood();
}
Vampire接口继承了Monster,Lethal俩个接口,而且使用了关键字extends,这就是java中的多继承。
参考资料:
java中的多继承
java接口多继承
-
问题2:对影子变量的概念理解模糊
-
问题2解决方案:查阅资料了解到:
1.在一个类中,子类中的成员变量如果和父类中的成员变量同名,那么即使他们类型不一样,只要名字一样。父类中的成员变量都会被隐藏。在子类中,父类的成员变量不能被简单的用引用来访问。而是,必须从父类的引用获得父类被隐藏的成员变量,一般来说,我们不推荐隐藏成员变量,因为这样会使代码变得难以阅读。其实,简单来说,就是子类不会去重写覆盖父类的成员变量,所以成员变量的访问不能像方法一样使用多态去访问。2.同名的实例方法被覆盖 ,同名的静态方法被隐藏 ,child类的getName实例方法覆盖 了parent的getName实例方法,chind的getKind方法隐藏 了parent类的getKind方法
3.隐藏 和覆盖 的区别在于,子类对象转换成父类对象后,能够访问父类被隐藏 的变量和方法,而不能访问父类被覆盖 的方法
4.如果需要访问父类被隐藏 的实例变量,加上super就好了,比如访问父类的name,写上super.name就好了
参考资料:
JAVA中方法和变量在继承中的覆盖和隐藏
-
问题3: 对课本上的抽象类概念理解模糊
-
问题3解决方案:通过查阅资料了解到该知识点与下一章的多态方面的知识联系密切。
抽象类就是为了继承而存在的,如果你定义了一个抽象类,却不去继承它,那么等于白白创建了这个抽象类,因为你不能用它来做任何事情。对于一个父类,如果它的某个方法在父类中实现出来没有任何意义,必须根据子类的实际需求来进行不同的实现,那么就可以将这个方法声明为abstract方法,此时这个类也就成为abstract类了。
抽象类和普通类的主要有三点区别:1)抽象方法必须为public或者protected(因为如果为private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为public。
2)抽象类不能用来创建对象;
3)如果一个类继承于一个抽象类,则子类必须实现父类的抽象方法。如果子类没有实现父类的抽象方法,则必须将子类也定义为为abstract类。
参考资料:
深入理解Java的接口和抽象类
Java中的抽象类
代码调试中的问题和解决过程
- 问题1:在做pp9.1项目时想直接引用父类Coin中的private变量face时失败,截图如下:
- 问题1解决方案:方法1:将变量修改为protected型变量,更好的理解了protected可见性提供了允许继承的最大可能的封装性。截图如下:
方法2:间接引用Coin类中的private变量face(不需要将private改为protected),方法是在Coin类中定义获得face的getFace()
方法 ,改过后的Coin类截图如下:
- 问题2:编写pp9.1项目时没有正确理解题意,我理解的是MonetaryCoin类的构造函数中直接使用Coin类中的构造函数执行抛硬币操作,如果是正面,面值就是1,反面就是0,而且要在MonetaryCoin类中定义一个方法获得面值。后来在与同学们交流的过程中意识到题意是这样的:我们可以通过MonetaryCoin类创建不同面值的对象,并且可以对这些对象使用Coin类中的
flip()
方法。
修改之前的MonetaryCoin类的截图如下:
修改之前的测试代码截图如下:
修改之后的MonetaryCoin类的截图如下:
修改之后的测试代码截图如下:
-
问题3:在实例化pp9.1项目中MonetaryCoin类时出现意料之外的错误,截图如下:
-
问题3解决方案:仔细检查之后发现开头少了
public static void main(String[] args) {
,改过后的截图如下:
代码托管
上周考试错题总结
-
错题1
理解:在Java中,数组被实现为对象。 -
错题2
理解:如果一个int数组作为参数传递给方法,int[] a
可为方法头定义参数列表 -
错题3
理解:语句保留了1000个引用变量的内存空间。注意,1000个BankAccount对象都没有实例化。 -
错题4
错因:不熟悉数组的定义方法的细节 -
关于数组的一些知识:
int []a,b;
是声明了a和b两个整数型数组;int a,b[];
是声明了一个整数型变量a和一个整数型数组b;int []a;
和int a[]
是等价的,都是声明一个整型数组a。
int[]a =new int[10]
这条语句是对整数型数组a进行了实例化;给数组中每个索引处赋值叫做对数组进行初始化。 -
错题5
理解: 直接将数组a变为数组b,也就是直接创造了一个新的数组,而不是复制。 -
错题6
理解:C项的意思为:初始化列表有4个int值,初始化意味着赋值。 -
错题7
理解:在java命令之后,在命令行输入的任何内容都将被接受为命令行参数。Java主方法使用参数(String[]变量),以便用户可以运行程序并提供“命令行”参数。由于参数是一个字符串数组,因此用户不必提供任何参数。 -
错题8
理解:只要只访问ArrayList的元素,它的效率与数组的效率差不多。只有当一个人开始在ArrayList的前部分插入或移除元素时,它的效率才会恶化。ArrayList是作为数组实现的,只要其中一个只是访问ArrayList的元素,效率与数组的效率是一样的。但是,当对ArrayList的前部分进行插入或删除时,就会发生大量的元素复制,从而降低其效率。
结对及互评
点评过的同学博客和代码
- 本周结对学习情况
-
结对学习内容
这周依旧没有一起讨论什么问题......可能是时机未到吧!
- 上周博客互评情况
感悟
继续坚持坚持坚持吧!
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 28/28 | 1/1 | 16/16 | |
第二周 | 710/738 | 1/2 | 20/36 | |
第三周 | 426/1164 | 1/3 | 16/52 | |
第四周 | 1068/2232 | 2/5 | 20/72 | |
第五周 | 604/2928 | 1/6 | 22/94 | |
第六周 | 609/3537 | 1/7 | 22/116 | |
第七周 | 599/4136 | 1/8 | 18/134 |
-
计划学习时间:20小时
-
实际学习时间:18小时
-
改进情况:坚持到底!