南昌航空大学软件学院OO第一单元(前四周)作业总结
一:前言
关于PTA布置的前三次作业做出总结,三次作业得分都为100分。第一和第二次作业,基本都是对数据的处理以及对算法的考察,基本上根据面向过程思想来对编程能力进行考察,所以完成的比较轻松,也很快的就完成了作业。第三次作业开始逐渐从面向过程转变为面向对象,刚开始老师讲的比较抽象,之前也习惯了面向过程进行编程,所以刚开始写第三次作业时遇见了很多问题,比如很多JAVA的语法、语句不清楚,面向对象的思想难以理解等。但最后通过询问老师与同学,网上查里面,将软件世界抽象的思想通过现实世界的类比,也是成功的完成了第三次作业。
二:作业过程总结
①:作业之间知识迭代关系
第一次作业主要考察了java语言的语句以及选择结构if else语句、循环结构for循环、while循环以及do while循环和对基本数据类型int、double、char、boolean等基本数据类型和对数组结构的考察,作业总体上难度不大,与之前学习的C语言基本类似,编程也还停留在面向过程中。
第二次作业在第一次作业考察基本数据类型、基本数据结构、编程语法语句的同时,还加大了对数据处理的要求,和对日期类算法的考察,和对函数方法的调用,函数的调用使得程序更加模块化,日期类算法考察了我们编程的逻辑性以及对日期中存在的特殊情况的处理。
第三次作业开始逐渐从面向过程逐渐转变为面向对象,开始对java语言中的对象和类进行考察,比如类的可见性、构造函数、函数的调用、对象传值与调用等。考察了类的四种可见性public 所有可见、private 私有属性,仅对本类可见、protected 本包和子类可见default 本包可见(没有修饰符)。构造函数考察了构造函数的基本知识,java的构造函数的名称与类名一样,且没有返回值,每个类中都必须构造函数,如果没有显式构造函数,java编译器会自动为该类产生一个空的无参构造函数,且一个类可以有多个构造函数,只要形参列表不相同即可。在new一个对象时,根据实参的不同,会自动挑选相应的构造函数,如果实参形参匹配不上,系统将会报错。
②:从面向过程过渡到面向对象
前两次的作业还基本停留在面向过程的思想中,没有理解到面向对象程序设计的思想,和类和对象之间的关系,解题思路与上学期C语言大致相似,以过程为中心的编程思想,以什么正在发生为主要目标进行编程,分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。而第三次作业真正开始进入了面向对象世界,以对象作为基本程序结构单位的程序设计,用于描述的设计是以对象为核心,而对象是程序运行时刻的基本成分。用于描述的设计是以对象为核心,对象是程序运行时刻的基本成分。第三次作业的类设计就很好的体现了面向对象者一编程思想,充分发育了面向对象的优势与特点,开始真正的从面向过程过渡到面向对象。
③:作业过程中遇到的问题及解决方法
问题一:第一次作业7-4第14个测试点
该测试点测试了若三条边满足两直角边的平方和等于斜边的平方,开始使用普通double类型进行运算,若输入普通整数数据不会出现问题,当输入根号值的近似值如根号2、根号3、根号5时,由于无法输入根号数据只能输入数据的近似值,输入近似值时存在了误差,这时程序判定将是普通三角形而不是直角三角形。
这个测试点我在刚开始时并没有想到这个问题,后面问了同学和老师,慢慢悟到了其中的道理,后面尝试提高数据精度,通过使用大数类BigDecimal等一系列提高精度的方法进行运算,成功的解决了问
题。
问题二:第三次作业7-2 public DateUtil getNextNDays(int n);//取得year-month-day的下n天日期、public DateUtil getPreviousNDays(int n);//取得year-month-day的前n天日期函数
这两个函数以DateUtil类名作函数的返回值类型,一开始不明白类名作返回类型应该返回什么,通过查找资料,询问老师、学长、同学等慢慢搞懂了其中的原理,以类名作返回类型是返回该类的对象。
public DateUtil getNextNDays(int n) { int[] months = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; int sum = n + day; do { if (month == 2) { if (isLeapYear(year) == true) { months[month - 1] += 1; // 如果是闰年则2月加一天 } else { months[month - 1] = 28; // 如果不是闰年,则二月置为28天 } } if (sum - months[month - 1] > 0) { sum -= months[month - 1]; month++; if (month == 13) { year++; month = 1; } } } while (sum > months[month - 1]); day = sum; DateUtil g = new DateUtil(year, month, day); return g; }
如上计算天后函数,函数最后DateUtil g = new DateUtil(year, month, day); return g;是定义了一个对象g,这个对象包含了计算后的年月日,最后返回这个DateUtil类的对象g,就符合了以类名作返回类型的法则。
问题三:作业7-2public int getDaysofDates(DateUtil date);//求当前日期与date之间相差的天数函数
这个函数的算法与第二题类似,我通过计算两个日期分别与日期01-1-1求天数差,通过比较两个天数差的大小,来计算两个日期的天数差。这道题算法方面比较容易,但一开始的问题来源于将date对象作参数
传入函数,如何将year,month,day的值传入函数,通过学习课程、和查找资料我了解到通过get函数来获取函数本身对象的值和作参数传入对象的值。
public int getDaysofDates(DateUtil date)// 求当前日期与date之间相差的天数 { int sum = 0; if (equalTwoDates(date) == true) { sum = 0; } else { for (int i = 1; i < date.getYear(); i++) { if ((i % 4 == 0 && i % 100 != 0) || (i % 400 == 0)) { sum += 366; } else { sum += 365; } } for (int i = 1; i < date.getMonth(); i++) { if (i == 1 || i == 3 || i == 5 || i == 7 || i == 8 || i == 10) { sum += 31; } else if (i == 2) { if (date.getYear() % 4 == 0 && date.getYear() % 100 != 0 || date.getYear() % 400 == 0) { sum += 29; } else { sum += 28; } } else { sum += 30; } } sum = sum + date.getDay(); int sum1 = sum; sum = 0; for (int i = 1; i < year; i++) { if ((i % 4 == 0 && i % 100 != 0) || (i % 400 == 0)) { sum += 366; } else { sum += 365; } } for (int i = 1; i < month; i++) { if (i == 1 || i == 3 || i == 5 || i == 7 || i == 8 || i == 10) { sum += 31; } else if (i == 2) { if (isLeapYear(year) == true) { sum += 29; } else { sum += 28; } } else { sum += 30; } } sum = sum + day; int sum2 = sum; if(sum1>sum2) { sum=sum1-sum2; } if(sum1<sum2) { sum=sum2-sum1; } } return sum; }
如上代码date.getYear()通过调用传入对象date的方法getYear()来获取对象year的值,而该函数的本身对象通过year来获取他的值,获取两个值之后,按上述算法计算得两个日期之间的天数差。
问题四:第三次作业7-3、7-4作业UML图的阅读
刚开始看到UML图很懵,通过查找资料了解了UML图的阅读以及UML类图的几种关系。
上述资料引自CSDN博主jieniyimiao “UML类图几总关系总结”博客,仅供参考。
原文链接:https://blog.csdn.net/u013467442/article/details/41808501
④:每次作业花费的时间比例
三次作业花费的时间比例大致为 2:3:10,原因在于第一次作业、第二次作业多在于算法、语句、和基本数据结构的考察,这类知识在上学期的C语言学习中具有一定的基础,使用和理解起来也较为容易,作业完成整体也比较轻松。第三次作业较前两次作业花费了更多的时间,原因在于从面向过程逐渐转变为面向思想,刚开始很不习惯,因为之前都是面向过程编程,给个人的编程习惯上烙下了很深的烙印,一开始来改变比较困难,需要时间,而且面向对象涉及很多新的知识很多都需要自学或查资料慢慢摸索与理解,我在查资料和自学新东西花费了绝大多数时间,反而在写代码花费的时间没有这么多,而面向对象很多知识例如类、对象等都是抽象的,需要类比现实世界的东西来更好的理解。
三:OO设计心得
①:面向过程与面向对象的比较
一:编程思想不同
我觉得面向过程与面向对象最大的区别就是编程的思想不同,面向过程是一种以过程为中心的编程思想,都是以什么正在发生为主要目标进行编程,更强调方法与动作,所有的变量都是被动的参与进来,没有自主决定权。而面向对象是一类以对象作为基本程序结构单位,指用于描述的设计是以对象为核心,方法属于每个对象,能否实现是每个对象说了算的,对象具有自主思想与精神,对象是程序运行时刻的基本成分。
二:特点不同
面向过程是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。而面向对象具有识认性,系统中的基本构件可识认为一组可识别的离散对象,对象具有唯一的静态类型和多个可能的动态类型,在基本层次关系的不同类中共享数据和操作。
三:优势不同
面向过程不支持丰富的“面向对象”特性(比如继承、多态),并且不允许混合持久化状态和域逻辑。而面向对象在内部被表示为一个指向一组属性的指针。任何对这个对象的操作都会经过这个指针操作对象的属性和方法。
②:面向对象设计的基本原则理解
面向对象其实就是现实世界原则的抽象。现实世界是对象和对象之间相互作用共同组成的,先有对象后有类,而在软件世界中先有类再有对象。每个对象都有自己特有的属性,例如人具有身高、体重、性别、年龄等属性,这与现实世界是相同的,且每个对象都有自己专有的方法。外部对象如果想要调用这些方法,可以向它请求并传入参数,等方法执行结束后返回结果,这就相当于现实世界,如果你想了解他人的信息,你必须想他人询问并请求。对象就是一个变量,一个具体的东西,类就是类型,从万千对象中抽取共性,对象是类的具体实现。对象不仅包括成员变量,还要成员方法,并且对象的内容也等同于现实世界自然规则是可以继承的,子类继承父类,父类继承曾父类,对象的内容也可以继承。
③:OO编程思维的理解
我目前理解oo编程思维最主要的基本元素是类和对象,类就相当于现实世界人的一种标签,例如南昌航空大学软件学院19201512学生是15班的,是19级的,是软件学院的,是南昌航海大学的学生,诸如此类标签,oo编程思想中的类就相当于这一些标签,而对象就相当于现实世界的一个人,相当于学号19201512这个人。oo设计主要任务是将设计尽量和现实世界的事务一致化。尽量使程序设计的思路符合现实世界事务的规律。类和对象 是oo编程中最重要最基本的两个元素,在设计时,先将找到要处理的各个对象,再找到各个对象的共同的祖先,逐层抽象。最后确立各个类之间的继承关系。所有综上,我对oo的理解很大程度上类比于与现实世界,类与对象就相当于软件维度的东西。其实本质上是与现实世界一样的。
四:测试的理解与实践
①:测试对于编码质量的重要性
软件的质量除了靠程序员编写时代码的正规化和代码的严谨程度之外,很重要的一环就是代码的测试,测试是什么?测试就是对开发的代码产品进行差错审查,保证代码质量的一个过程,测试是对代码对象进行审查与测试,他对于程序最终的质量起了至关重要的作用,在很多软件大厂都设有软件测试工程师这一职位,从各种角度来看,测试对于代码质量十分重要且不可缺少。
②假如让你设计测试用例,你会如何做
如果让我设计测试用例,我会选择那些容易出问题的用例,例如在日期类中求n天后日期,我会选择闰年二月的最后一天这种特殊样例,例如2020年2月29日后1天,专门找这种容易出bug的测试用例,且要保证用例的正确性,并且从多方面进行多次测试,避免出现偶然性。
四:课程收获
这四周在oo课程最大的收获就是编程思想逐渐从单一的面向过程逐渐转变为面向对象,更加了解了面向对象的核心思想,也学会了利用现实世界与软件世界进行类比,本质上软件世界与现实世界是相通的,这更有利于我们对面向对象思想的理解。并且加强了我的自学能力和独立思考能力,在完成作业的过程中会遇到很多问题,并且很多老师都没怎么讲过,这时候就需要自己独立思考、通过查资料、问老师等方法来解决。
五:对课程的建议
希望老师可以讲解PTA或者我们自己写过的作业,因为自己写的作业自己思考过,每个人知道自己的问题在哪里,带着问题去学习相比于课堂上的书本上的代码样例可能更能带来触动,并留下更深的印象!