第一次Blog作业-前五周学习阶段性总结
在前五周的学习中,学习了第九章到第十三章的相关内容,在面向对象程序设计这一块,主要学习了以下内容:
学习内容
1.面向对象七大设计原则:
开闭原则:
对扩展开放,对修改关闭。(主要是保证代码的安全性)
里氏代换原则:
子类(派生类)有的方法,父类(基类)一定有。子类可以代替父类创建对象。
迪米特里法则:
1.不要和陌生人说话。
2.只和你的直接朋友通信。
3.最少知识原则。
单一职责原则:
一个类只存在一个让它发生改变的原因,只能让一个类或接口有且只有一个职责。
接口隔离原则:
使用多个专门的接口比使用单一的总接口总要好。
依赖倒转原则:
顶层打交道,底层不打交道,即高层模块不应该依赖于低层模块,二者都应该依赖于抽象。
合成复用原则:
尽量使用组合和聚合,尽量不使用继承。
2.面向对象三大特性
继承,封装,多态
封装:将客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏,按照慕课的说法,就是把数据和对这些数据的操作放在一起,并且用这些操作把数据掩盖起来,封装是面向对象的基本概念之一。
在Java中类中成员的属性有:public, protected, <default>, private,这四个属性的访问权限依次降低。
继承:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。被继承的类被称为父类或基类,继承者被称为子类或派生类。父类中的抽象方法必须在子类中得到实现,父类可以通过下转型子类来实现实例化。如 父类名+变量名=new+子类名(参数);
多态:允许将子类类型的指针赋值给父类类型的指针。事实上,在继承方法中,多态就是一种在父类中创建抽象方法,让不同的子类中的同名方法具有不同的功能实现,可以理解为”一种抽象方法的不同实现形式“。
实现多态
1.覆盖:子类重新定义父类的方法的做法。
2.重载:允许存在多个同名方法,但这些方法的参数不同(数量,类型)。
3.设计模式
1.MVC框架模式(model,controller,view即实体类,控制类,接口类):
经典MVC模式中,M是指业务模型,V是指用户界面,C则是控制器,使用MVC的目的是将M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式。
2.单例模式:
一个类仅有一个实例,并提供一个访问它的全局访问点。
3.工厂模式
类似于一个工厂类里装了许多产品类,当需要使用什么就调用什么类,不太推荐使用。
在PTA上进行了三次练习。
第一次如下
第一题用类解一元二次方程式,主要考察对类的创建与实例化以及JAVA语法等基础知识第二题日期类设计,
第二题,根据题目要求,不允许使用与日期相关的类与方法。我解决这道题的方法是创建了一个DateUtil类,通过三个方法分别实现求下n天,求前n天,求两个日期相差的天数等功能,并且有一个闰年判定方法以及一个返回本年天数的方法。
第三题、第四题与第二题大同小异,题目的要求用相关类图进行表示,两道题同样都是要求用四个类进行设计(DateUtil,Day,Year,Month),不同的是,第四题的设计方式明显优于第三种,如果再添加一个接口类便可以形成MVC模式。
第二次如下
第二次作业因为出题老师的不同,主要考察的方向也不同。
第二次作业主要考察IO,字符流以及一些基本的语法,难度上有所下降,但是说实话,题目与设计并不太相关,唯一令人印象深刻的就是这位出题老师在每道题里都隐含了一个必须用float而不能用double输出的设定,如果不是同学告诉我,我估计只能得到"Wrong Format“的分数,最后解决的方法是将每道题得到的结果以及中间的一些过程都用(float)进行数据类型的转换。
第三次如下
第三次作业与第二次作业都是同一位老师的产物,这次作业主要还是考察IO的转化,
第一题使用toUpperCase()方法将所有输入的字母都转化为大写,然后用charAt()方法提取字符,用ascii码进行判定并求数,将得到的字母对应的数字存在一个数组中,如果最后判定没有数据格式输入错误,便用for循环遍历输出数组。
第二题比较简单,只要算好位数便可以进行检测,用到了length方法检测位数,charAt()方法得到该位的数值,并且自己写了一个judge方法来检测奇偶,没多久就通过了。
第三题使用substring()方法对特点位数的数据进行检测,其他的方法与其他两题相似,这道题依然是对IO以及字符流的考察,不是很有实际意义,只有工作量,没有难度。
然后是超新学习通上的练习与实验
其中雨刷问题是超新学习通上持续最久的作业,
第一次分为三种编程语言python,java,c进行编写,感受到了面向对象语言与其他语言的区别,虽然JAVA的速率与两位不能相比,但多文件,扩展性,跨平台等优势让JAVA成为了非常优秀的应用类编程语言,
在第二次作业时从一开始的四个类不断加成,重构代码,使得各个实体类、方法实现单一职责化。
在第三次作业时规范了代码格式,并使得符合迪米特法则,如接口类作为一个GUI类,并不与控制类直接相连,而所有的实体类又只和控制类相连且实体类之间互不相连。
第四次作业时运用了双重校验锁实现单例,规范了MVC模式,比较显著的是大幅减少了Main主函数的体量,从而把处理功能都交给控制类control,各个模块类也可以更加高效的发挥作用。
第五次作业时对Lever,Dial,Control,Brush四个类进行了抽象处理,并添加了相应的子类。
总结
这三周的学习下,渐渐熟悉了类的封装,类与类之间的关系,同时通过PTA,Mooc,超新学习通等学习平台进行了大量的练习,巩固了学习的知识,同时通过不断学不断用,在其他平台也获取了不少实用的JAVA编程知识,如JAVA上几种不同的数据类型转换,parse以及(转换的数据类型)等方法。
而且,在不断的练习中,逐渐规范了JAVA代码的编写,不再像寒假初学JAVA时那样经常以f(),t()等单个字母对方法或变量进行命名,同时随着代码量的增大,也学会了写注释来标注各个模块。同时,因为每次交超新学习通作业都要交类图,所以也渐渐熟悉了类图的各项含义同时在学习中,理解了Java的内存划分,能够熟练进行数组的声明、创建及使用,并在程序中灵活应用。
最后,建议PTA的出题老师尽量以实际情况下的情景来出题,不要老是出一些没有实际意义的题目,抽象的十题也比不过形象的一题。
常见Bug
abstract类中的abstract方法的多态化有时会因为子类没有这种方法而报错,注意,如果在父类中定义了abstract方法,那么在子类中一定要将其实现,如果并不需要使用这个方法,可以在子类方法中不加内容,也可以返回null,但是一定要实现。
手打nextLine方法经常打成nextline,这种格式错误在现在的编译软件中可能很好避免,但是如果你只是在文本里微调一下代码,那就要注意别写错。
String.split()方法括号中的内容数据类型为字符串,即使你只是想用单个字符来表示,也不要忘了给它套上双引号。
String.substring(int x,int y)方法括号中的数为字符串中的第x位到第y位但不包括y位,如果你想要遍历到y位,记得要加一,如果要从x位遍历到最后一位,只要把后面那个参数连同那个逗号一同去掉就行。
一些反思
如果一个问题你很久都没有解决,且不是编译错误的话,第一检查逻辑问题,第二检查格式问题(如PTA),之前在PTA做题的时候就深受其害,注意换行,之前简单调试代码是在代码的某些地方进行部分数据的输出,但是在提交代码的时候忘了删除,就会造成错误,而且一时半会还想不到这个部分,所以建议各位老老实实用编译器里的调试器。
不要把父类里的所有方法都定义成抽象方法,虽然无伤大雅,但是在写代码的时候还是要尽量遵循逻辑的严谨性,比如你设置一个动物类,然后其中有一只羊,一只狼和一个卷心菜,如果你将吃羊这个方法在动物类中进行了抽象定义,最终的结果就是羊子类中会出现一个吃羊的方法,卷心菜子类中也会有一个吃羊的方法,即使这个方法的具体功能你只在狼子类中进行了实现,但是这个代码在逻辑上着实不可靠。
最近收获
最近学到了一个比较使用的数据转换异常处理的方法try{}catch(){},可以处理大部分数据转换中的异常情况。
如果对IO,字符流这方面的处理感到头疼的话,不妨去学习一下正则表达式,可以为以后的学习与作业减少弯路,比如这次的PTA作业就可以用上。