20155303 2016-2017-2 《Java程序设计》第四周学习总结
教材学习内容总结
第六章 继承与多态
6.1 何谓继承
继承避免多个类间重复定义共同行为,使用关键字
extends
。继承表明了子类与父类之间的is-a
关系,中文称为“是一种”。子类继承父类之后,定义与父类中相同的方法部署,但执行内容不同,这称为“重新定义” ,即“重写”(Override)。多态是使用单一接口操作多种类型的对象。
@Override
是一个内建的标准标注。如果在子类中某个方法前标注@Override
,表示要求编译程序检查,该方法是不是真的重新定义了父类中的某个方法,如果不是的话,就会引发编译错误。如果某方法区块中没有任何程序代码操作,可以使用
abstract
标示该方法为抽象方法。该方法不用撰写{}区块,直接;结束即可。如果尝试用抽象类创建实例,就会引发编译错误。
6.2 继承语法细节
被声明为
protect
的成员,相同包中的类可以直接存取,不同包中的类可以在继承后的子类直接存取。依权限大小可分为
private
、无关键字、protected
与public
。
在Java中,如果想取得父类中的方法定义,可以在调用方法前,加上
super
关键字。可以使用super
调用的父类方法,不能定义为private
(因为这就限定只能在类内使用)。重新定义方法要注意,对于父类方法中的方法权限,只能扩大不能缩小。若原来成员
public
,子类重新定义时不可为private
或protected
。如果想执行父类中某构造函数,可以使用
super()
指定。如:super(10)
表示调用父类构造函数时传入int
数值10。如果
class
前使用了final
关键字定义,那么表示这个类是最后一个了,不会再有子类,也不会被继承。在Java中,任何类追溯至最上层父类,一定是
java.lang.Object
。在
go()
方法中,可以调用抽象方法。
第七章 接口与多态
7.1 何谓接口
在Java中可以使用
interface
关键字定义行为。类要操作接口,必须使用
implement
关键字。操作某接口时,对接口中定义的方法有两种处理方式:一是操作接口中定义的方法,二是再度将该方法标示为abstract
。继承有“是一种”的关系,操作接口则表示“拥有行为”。
在Java中,类可以同时继承某个类,并操作某些接口。
在Java中,接口可以继承自另一个接口,也就是继承父接口行为,再在子接口中额外定义行为。
7.2 借口语法细节
在Java中可以使用
interface
定义抽象的行为和外观。接口中的方法没有操作时,一定得是公开且抽象。在接口中枚举常数,一定要使用“=”指定值,否则会编译错误。
在撰写Java程序时,经常会有临时继承某个类或操作某个接口并建立实例的需求。由于这类自类或接口操作类只使用一次,不需要为这些类定义名称,因此可使用匿名内部类来解决这个需求。
-
enum可用于定义枚举常数。
教材学习中的问题和解决过程
『问题一』: Java字符串格式化
String.format()
的使用问题
课本P172出现了String.format()
作为返回值,但关于format()
方法的用法课本上并没有解释。
『解决』:在一篇JAVA字符串格式化String.format()的使用方法的博客中学习到,String类的format()方法用于创建格式化的字符串以及连接多个字符串对象。不同转换符可以实现不同数据类型到字符串的转换。
- 『问题二』:对Java“高内聚,低耦合”的理解
这周去找学长请教问题的时候,听到他说“最好不要在一个class里新建另一个class,在一个方法里调用另一个方法”。问他原因,他说,这违背了面向对象“高内聚,低耦合”的原则。那么,具体体现在哪些方面呢?
『解决』:之前老师在预备作业中让我们思考过这个问题,现在学习了一段时间Java,对这个原则有了更深刻的理解。对于低耦合,我的理解是:一个完整的系统,模块与模块之间,尽可能的使其独立存在。也就是说,让每个模块,尽可能的独立完成某个特定的子功能。模块与模块之间的接口,尽量的少而简单。如果某两个模块间的关系比较复杂的话,最好首先考虑进一步的模块划分。这样有利于修改和组合。高内聚则指在一个模块内,让每个元素之间都尽可能的紧密相连。也就是充分利用每一个元素的功能,各施所能,以最终实现某个功能。如果某个元素与该模块的关系比较疏松的话,可能该模块的结构还不够完善,或者是该元素是多余的。
在一篇Java高内聚、低耦合的理解的博客中,对这个原则进行了通俗易懂的解释。做到“高内聚,低耦合”,模块的“可重用性”、“移植性”也就大大增强了。
- 『问题三』:静态分配与动态分配
『解决』:所有依赖静态类型来定位方法执行版本的分派动作称为静态分配,静态分配发生在编译阶段,其典型动作是方法重载(Overload)。在运行期根据实际类型确定方法执行版本的分配过程称为 动态分配,它和多态性的另外一个重要体现——方法重写(Override)有着密切的关系。
- 『问题四』:
abstract class
与interface
(即 抽象类 与 接口)
『解决』:abstract class
和interface
是Java语言中对于抽象类定义进行支持的两种机制。不过,抽象类提供了继承的概念,它的出发点就是为了继承,否则它没有存在的任何意义。所以说定义的抽象类一定是用来继承的。接口是用来建立类与类之间的协议,它所提供的只是一种形式,而没有具体的实现。同时实现该接口的实现类必须要实现该接口的所有方法,通过使用implements
关键字,表示该类在遵循某个或某组特定的接口。
抽象类与接口有各自不同的使用方法,关于使用这两者时的注意事项,在博客java提高篇(四)——抽象类与接口有具体详尽的解释。
- 『问题五』:方法重载 与 方法重写
『解决』:多态性是面向对象编程的一种特性,和方法无关。静态多态性是指,同样的一个方法能够根据输入数据的不同,做出不同的处理,即方法的重载(有不同的参数列表)。动态多态性是指,当子类继承父类的相同方法,输入数据一样,但要有别于父类的相应时,就要覆盖父类方法,即在子类中重写该方法(相同参数,不同实现)。
- 『问题六』:
super.
与this.
『解决』:this表示当前对象,也就是当前类对象,super表示当前类的父类。例如:定义一个新的类A,这个A继承了类B,也就是说B是A的父类。那么如果A中有个方法:aa();B中也有个方法: aa();
那么在A 中用this.aa()调用的就是A中定义的方法,而super.aa()调用的就是A的父类B中定义的方法aa()。详细讲解参考博客super,this的区别和使用。
super.
如下:
this.
如下:
- 『问题七』:
add()
方法的使用
课本P179提到,“如果要收集对象,可通过add()
方法”。
『解决』:之前学习过java.math.BigDecimal
标准类中的add()
方法,java.util.ArrayList
中也有add()
的方法,查询API文档比较如下:java.util.ArrayList.add()
java.math.BigDecimal.add()
:
代码调试中的问题和解决过程
- 『问题一』: 标准备注
@Override
的使用
『解决』:在子类某个方法前标注@Override
之后,会出现左侧的提示,查看该方法重新定义的父类方法。
- 『问题二』:操作接口时缺少具体行为
如果类操作另一个类,没有定义行为时,程序会报错:
『解决』:操作类时,要注意定义行为。
- 『问题三』:
length
、length()
与size()
的区别
课本P179的程序和P180的程序分别用到了length
与 size()
,但不太清楚这两者的用法。
『解决』:参考博客java中length,length(),size()区别进行学习,了解到java语言中针对数组提供了length属性来获取数组的长度,针对字符串提供了length()方法来获取字符串的长度,针对泛型集合类提供了size()方法来获取元素的个数。所以三者的用法还是有区别的。编写了一个程序加深对这三者的理解:
- 『问题四』:一个很大的数与一个很小的数运算时,会发生消去误差。例如计算
1+1/2+1/3+...+1/n
时,从右向左计算会比从左向右计算得到更精确的结果。编写程序尝试了一下,却出现了以下的结果:
『解决』:没有考虑到类型转换问题,将sum += 1/i;
改为sum += (float) 1/i
后问题得到解决。
代码托管
- 代码提交过程及代码量截图:
上周考试错题总结
- Linux Bash中,(grep)命令可以进行全文搜索。
『考点』:grep是linux中很常用的一个命令,主要功能就是进行字符串数据的对比,能使用正则表达式搜索文本,并将符合用户需求的字符串打印出来。grep全称是Global Regular Expression Print,表示全局正则表达式版本,它的使用权限是所有用户。grep在数据中查找出一个字符串时,是以整行为单位来进行数据选取的。
格式及常用的参数如下:
- System.out.println(“”+52+25);的结果是(5225)
『考点』:System out println(""+i);
等价于System.out.println(i.toString());
。public String toString()
返回该对象的字符串表示。通常,ToString()
方法会返回一个“以文本方式表示”此对象的字符串。因此在本题中以字符串形式输出5225。
- p86 Guess.java中guess的值无法输入12。(X)
『考点』:代码:guess = scanner.nextInt();
表示获取输入的下一个整型数,而且程序中没有设置错误输入提醒,所以可以输入12.
- 可以使用java.util.Arrays的(fill())方法把数组初始化成相同的值。
『考点』:查询API文档可知,fill()方法的作用是Assigns the specified int value to each element of the specified array of ints.
,即:将指定的int值赋给数组的每个元素。
- “30”转化为byte类型的30的语句是(Byte.parseByte(“30”);)
『考点』:同样查询API文档可知,java.lang.Byte.parseByte()方法的作用是Parses the string argument as a signed decimal byte.
,即:将字符串参数转换为带符号的十进制数。
错题总结
考点均在所学范围内,但考察得非常细致,这就要求我们在学习过程中一定要认真对待敲过的每一行代码,弄懂学习过程中的每一个疑问。同时,API对Java的学习非常有帮助,对于不太理解的方法,我们都可以从API中获得满意的解释。综上,在今后的学习过程中要勤于动手,善于思考。
学习感悟
『关于学习过程与方法』学习Java课程第四周,我最大的感悟是:不能局限于把课本上的代码敲上去,而不进行任何思考,不然再次拿起课本还是一头雾水。另外,CSDN真的是一个超级厉害的网站!学习过程中遇到的问题基本上都能在CSDN上各位牛人的博客中找到答案。所以,学编程,经常逛逛其他人的经验分享,总会有很大收获。
『关于英语学习』本以为过了四六级,英语水平就能应付日常了,但是Java的学习让我意识到这还远远不够。很多时候在*搜到的文章都是英文的,图书馆也有很多关于编程的书籍只有英文版。看到这些,我只能咬咬牙,一边借助百度翻译,一边一个单词一个单词地啃,费时费力不说,理解还不一定准确透彻。So,本来每天在扇贝新闻阅读BBC报导的我,决定重新拾起扇贝单词,努力达到老师口中的“无障碍阅读英文著作”。
『关于Further Learning』新的一周总能认识到自己新的不足,遇到问题上网查阅资料的时候,这种体会尤为真切。网上的技术牛人太多太多,每次都是怀着近乎虔诚的心情点开博客,听过来人娓娓道来,细致讲解,深深明白自己的水平还与他们存在很大差距。所以,大学四年的结束不应该是我们学习的终结,而应该是一个新的开始。学无止境,希望所有人都能坚持“Lifelong-Learning”,在更深更远更广的领域开创出自己的一片天地。
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 16/16 | 1/1 | 18/18 | 初步认识了Java |
第二周 | 219/235 | 1/2 | 28/46 | 学习了Java的基本语法知识 |
第三周 | 766/1001 | 1/3 | 23/69 | 了解对象与参考的关系,以及封装的概念与实现 |
第四周 | 984/1985 | 1/4 | 18/87 | 学习了继承与多态的关系,以及接口的多态操作 |
尝试一下记录「计划学习时间」和「实际学习时间」,到期末看看能不能改进自己的计划能力。这个工作学习中很重要,也很有用。
耗时估计的公式
:Y=X+X/N ,Y=X-X/N,训练次数多了,X、Y就接近了。
计划学习时间:25小时
实际学习时间:18小时
改进情况:这周的学习任务不算轻松,本应花费再多一点的时间理解学习。以后还是应该提高学习效率,同时挤出时间进行深入思考,巩固薄弱知识点。