南昌航空大学软件学院OO第二单元(5-8周)作业总结

0.前言

关于5-8周的三次pta作业做出总结,三次作业得分分别为,第五次作业为92分,第六次作业为82分,第7次作业为130分(加上附加题)。从分数上来说,较之前阶段三次作业都得了100分有所退步,应该反思。第五次作业考察了正则表达式对输入字符串数据进行合法性校验及计算和对java中字符串处理类的使用的考察,还考察了LocalDateTime的使用、类的继承与聚合等关系。第六次作业考察了类的继承与多态、正则表达式对输入字符串数据进行合法性校验和处理。第七次作业考察了类的继承、类的多态性以及接口的应用。总的来说三次作业较上一阶段难度上有所增加,考察了正则表达式对输入数据的校验、类的继承、封装、多态性和类的接口的使用。

1.作业过程总结

一:三次作业之间的知识迭代关系

第五次作业最主要的考察了正则表达式的使用,利用正则表达式对输入的数据进行校验,从而达到用户输入的数据符合系统校验格式的效果,还考察了JAVA中一些数据处理类如LocalDateTime类、和一些字符串类如StringBulder、StringBuffer类以及类的多态、继承,和类之间数据传递的考察。

第六次作业和第五次作业整体上差不多,也是主要的考察了正则表达式的相关知识,利用正则表达式对输入的数据进行校验,和类的继承、多态的考察,以及对类与类之间数据传递以及数据处理的考察。

第7次作业主要考察了类的继承、多态性和JAVA中一些接口的使用,此外还增加一个附加题,考察对求素数算法的设计与优化。

总的来说三次作业考察的知识大多类似,基本上都是考察正则表达式的相关知识、类的继承、多态性和JAVA中一些类的使用和接口的使用。

二:如何通过作业逐步理解面向对象的封装性、继承性与多态性三大技术特性

封装性:

(1)在Java中,最基本的封装单元是类。
(2)类是基于面向对象思想编程语言的基础,程序员可以把具有相同业务性质的代码封装在一个类里,通过接口方法向外部代码提供服务,同时向外部代码屏蔽类里服务的具体实现方式。
(3)数据封装的最重要的目的是在于要实现“信息隐藏(Information Hidding)”。
(4)在类中的“数据成员(属性)”或者“方法成员”,可以使用关键字“public”、”private”、”protected”来设置各成员的访问权限。
(5)封装性是面向对象程序设计的原则之一。 它规定对象应对外部环境隐藏它们的内部工作方式。良好的封装可以提高代码的模块化程度,它防止了对象之间不良的相互影响。使程序达到强内聚(许多功能尽量在类的内部独立完成,不让外面干预),弱耦合(提供给外部尽量少的方法调用)的最终目标。
 
上述资料引自CSDN博主星云999 “Java之路:类的封装、继承与多态”博客,仅供参考。

原文链接:https://blog.csdn.net/qq_43555323/article/details/84788284
 
继承性:
在这阶段的作业中,多次考察了继承性。
例如第五次作业7-3图形继承
  1 import java.util.Scanner;
  2 
  3 public class Main {
  4 
  5     public static void main(String[] args) {
  6         // TODO 自动生成的方法存根
  7         double n;
  8         Scanner input = new Scanner(System.in);
  9         n = input.nextDouble();
 10         if (n < 1 || n > 4) {
 11             System.out.println("Wrong Format");
 12         } else {
 13             if (n == 1) {
 14                 double radius = input.nextDouble();
 15                 if (radius < 0) {
 16                     System.out.println("Wrong Format");
 17                 } else {
 18                     Circle cir = new Circle(radius);
 19                     System.out.println("Circle's area:" + String.format("%.2f", cir.getArea()));
 20                 }
 21 
 22             }
 23             if (n == 2) {
 24                 double length = input.nextDouble();
 25                 double width = input.nextDouble();
 26                 if (length < 0 || width < 0) {
 27                     System.out.println("Wrong Format");
 28                 } else {
 29                     Rectangle rec = new Rectangle(length, width);
 30                     System.out.println("Rectangle's area:" + String.format("%.2f", rec.getArea()));
 31                 }
 32 
 33             }
 34             if (n == 3) {
 35                 double radius = input.nextDouble();
 36                 if (radius < 0) {
 37                     System.out.println("Wrong Format");
 38                 } else {
 39                     Ball ball = new Ball(radius);
 40                     System.out.println("Ball's surface area:" + String.format("%.2f", ball.getArea()));
 41                     System.out.println("Ball's volume:" + String.format("%.2f", ball.getVolume()));
 42                 }
 43 
 44             }
 45             if (n == 4) {
 46                 double length = input.nextDouble();
 47                 double width = input.nextDouble();
 48                 double height = input.nextDouble();
 49                 if (height < 0 || length < 0 || width < 0) {
 50                     System.out.println("Wrong Format");
 51                 } else {
 52                     Box box = new Box(width, length, height);
 53                     System.out.println("Box's surface area:" + String.format("%.2f", box.getArea()));
 54                     System.out.println("Box's volume:" + String.format("%.2f", box.getVolume()));
 55                 }
 56 
 57             }
 58         }
 59     }
 60 
 61 }
 62 
 63 class Shape {
 64     public Shape() {
 65         System.out.println("Constructing Shape");
 66     }
 67 
 68     public double getArea()// 求图形面积
 69     {
 70         return 0.0;
 71     }
 72 }
 73 
 74 class Circle extends Shape {
 75     private double radius;
 76 
 77     public Circle(double radius) {
 78         this.radius = radius;
 79         System.out.println("Constructing Circle");
 80     }
 81 
 82     public double getRadius() {
 83         return radius;
 84     }
 85 
 86     public void setRadius(int radius) {
 87         this.radius = radius;
 88     }
 89 
 90     public double getArea()// 求图形面积
 91     {
 92         return (getRadius() * getRadius() * Math.PI);
 93     }
 94 }
 95 
 96 class Rectangle extends Shape {
 97     private double width, length;
 98 
 99     public Rectangle(double width, double length) {
100         this.length = length;
101         this.width = width;
102         System.out.println("Constructing Rectangle");
103     }
104 
105     public double getWidth() {
106         return width;
107     }
108 
109     public void setWidth(double width) {
110         this.width = width;
111     }
112 
113     public double getLength() {
114         return length;
115     }
116 
117     public void setLength(double length) {
118         this.length = length;
119     }
120 
121     public double getArea()// 求图形面积
122     {
123         return (getWidth() * getLength());
124     }
125 }
126 
127 class Ball extends Circle {
128 
129     public Ball(double radius) {
130         super(radius);
131         System.out.println("Constructing Ball");
132         // TODO 自动生成的构造函数存根
133     }
134 
135     public double getArea()// 求图形面积
136     {
137         return (4 * Math.PI * getRadius() * getRadius());
138     }
139 
140     public double getVolume()// 求球体积
141     {
142         return ((4 * Math.PI * getRadius() * getRadius() * getRadius()) / 3);
143     }
144 }
145 
146 class Box extends Rectangle {
147     private double height;
148 
149     public Box(double width, double length, double height) {
150         super(width, length);
151         this.height = height;
152         System.out.println("Constructing Box");
153         // TODO 自动生成的构造函数存根
154     }
155 
156     public double getHeight() {
157         return height;
158     }
159 
160     public void setHeight(double height) {
161         this.height = height;
162     }
163 
164     public double getArea()// 求图形面积
165     {
166         return (2 * (getWidth() * getLength() + getLength() * getHeight() + getWidth() * getHeight()));
167     }
168 
169     public double getVolume()// 求立方体体积
170     {
171         return (getWidth() * getLength() * getHeight());
172     }
173 }

在这题中,Circle、Rectangle、Ball、Box类继承了Shape类,为Shape类的子类,Shape类中构造方法输出Constructing Circle,getArea方法要求求图形的面积,在子类Circle、Rectangle、Ball、Box中继承了父类的构造方法并对父类的getArea方法进行重写,从而实现了类的继承。在JAVA中类的继承类比于现实世界,比如父亲的头发的卷发,儿子的头发也是卷发,儿子继承了父亲的特性,在JAVA中也是如此,子类会继承父类所有的属性与方法(但是不能直接访问private成员),根据信息隐藏原则,子类会继承父类所有的方法,并且可以直接使用,子类也会继承父类的父类的所有的方法与属性。在这题中,所有子类都继承了父类Shape的构造方法和getArea()方法,很好的实现的JAVA类的继承。并且Object是所有类的父类,是JAVA中类的始祖,Java之中不允许多重继承,但是却可以使用多层继承,相当于在现实世界中所有人都只有一个父亲,但是可以多重继承,可以继承父亲的特性,也可以继承爷爷的特性 一般情况下,在我们所编写的代码时,多层继承的层数之中不宜超过三层。

多态性:

多态(Polymorphisn),从字面上理解,多态就是一种类型表现出多种状态。这也是人类思维方式的一种直接模拟,可以利用多态的特征,用统一的标识来完成这些功能。在Java中,多态性分为两类:

(1)方法多态性,体现在方法的重载与覆写上。方法的重载是指同一个方法名称,根据其传入的参数类型、个数和顺序的不同,所调用的方法体也不同,即同一个方法名称在一个类中有不同的功能实现。方法的覆写是指父类之中的一个方法名称,在不同的子类有不同的功能实现,而后依据实例化子类的不同,同一个方法,可以完成不同的功能。
(2)对象多态性,体现在父、子对象之间的转型上。
在这阶段的作业中,大多数都是通过通过实现方法的多态性,通过子类继承父类的方法,再对继承的方法进行重写,从而实现多态性。
例如第六次作业7-1图形继承与多态中,子类继承了父类Shape的getArea()、validate()、toString()方法,但是由于各种图形求面积的方法不一样,例如长方形面积=长乘宽,圆形面积=PI*r*r。所以需要在子类中对getArea()方法进行重写,从而正确的实现每种图形的getArea()方法,实现多态性。多态性意味着,父类给子类一些方法和属性,子类通过对这些方法和属性进行重写,从而实现该种属性和方法表现出多种形态,从而实现多态。父类对象依据被赋值的每个子类对象的类型,做出恰当的响应(即与对象具体类别相适应的反应),这就是对象多态性的关键思想 同样的消息或接口在发送给不同的对象时,会产生多种形式的结果,这就是多态性本质
 

三:作业过程中遇到的问题及解决方法

第五次作业:第五次作业中,最主要的是考察了正则表达式,通过使用正则表达式从而实现对输入数据的校验,使用户输入的数据匹配正确的格式,正则表达式在一开始上课听讲时,基本概念与思想比较好理解,但当在作业中使用正则表达式时遇到了很大的困难,由于刚开始来使用,很多正则表达式都不熟悉,遇到了很多问题。

解决方法:通过网上查阅相关资料,询问同学,并对正则表达式的使用进行测试,解决了一些问题,但依然不是特别熟悉正则表达式,以后会加强相关方面的训练,更好的掌握正则表达式的相关知识。

第六次作业:第六次作业中,主要也是考察了正则表达式,和类的继承,以及对类的数据的处理,和对ArrayList类相关知识的考察,ArrayList类一开始在运用时候不了解,导致题目无法做下去。

解决方法:通过网络上查资料询问同学,我把ArrayList理解为一个对象数组,与数组类似,只不过它里面储存的内容为一个个对象,通过add()方法来实现对ArrayList里面元素的添加,通过for循环,来实现对ArrayList里面元素的访问以及处理,成功的解决了问题,也熟练的掌握的ArrayList类的相关知识。

第七次作业:第七次作业主要考察了类的继承与多态、以及对类的接口的运用,第七次作业7-1题不仅要求计算图形的相关面积,还要求对图形的面积进行排序输出,运用传统的选择排序处理起来麻烦,代码的运行时间也较长。7-2题中,在第一题的基础上还要求了对图形分组分类后再排序输出,对数据处理要求也更为严苛。

解决方法:在Card类里面实现了Comparable接口,并且运用compareTo()方法实现对ArrayList里面的数据进行排序。在7-2题中,针对对图形分组分类的要求,我又创建了一个criList的对象数组,在cardList储存总的图形对象的同时,CriList专门储存圆形对象,从而达到对图形进行分类,再分别调用compareTo,实现对分组分类后的图形对象进行排序。从而达到,不仅要对图形进行分类还要对其排序的要求。

class DealCardList {
    ArrayList<Card> cardList = new ArrayList<Card>();
    ArrayList<Card> cirList = new ArrayList<Card>();
    ArrayList<Card> recList = new ArrayList<Card>();
    ArrayList<Card> triList = new ArrayList<Card>();
    ArrayList<Card> traList = new ArrayList<Card>();

    public DealCardList() {

    }

    public DealCardList(ArrayList<Integer> list) {
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i) == 1) {
                double radius = Main.input.nextDouble();
                cardList.add(new Card(new Circle(radius)));
                cirList.add(new Card(new Circle(radius)));
            }
            if (list.get(i) == 2) {
                double width = Main.input.nextDouble();
                double length = Main.input.nextDouble();
                cardList.add(new Card(new Rectangle(width, length)));
                recList.add(new Card(new Rectangle(width, length)));
            }
            if (list.get(i) == 3) {
                double side1 = Main.input.nextDouble();
                double side2 = Main.input.nextDouble();
                double side3 = Main.input.nextDouble();
                cardList.add(new Card(new Triangle(side1, side2, side3)));
                triList.add(new Card(new Triangle(side1, side2, side3)));
            }
            if (list.get(i) == 4) {
                double topSide = Main.input.nextDouble();
                double bottomSide = Main.input.nextDouble();
                double height = Main.input.nextDouble();
                cardList.add(new Card(new Trapezoid(topSide, bottomSide, height)));
                traList.add(new Card(new Trapezoid(topSide, bottomSide, height)));
            }
        }
    }
//关键的分别创建图形List代码

四:作业花费的时间比例

三次作业花费时间比例大概在3天:3天:1天。因为第五次、第六次作业中涉及到正则表达式的相关知识,而我在正则表达式方面相对薄弱,花费了大量的时间去琢磨与研究相关知识,且第五、第六次作业难度较大,类于类之间的关系复杂,每个类中的方法也较多,且每一个方法的都不可缺少,完成的难度较大,花费了大量的时间。第7次作业主要的难度在如何正确的创建图形的List和对ArrayList类方法的了解与掌握,以及对类接口的使用,只要解决了这几个问题,作业就很好完成,花费的时间相对其它两次也较少。

五:对编程过程的严谨性的认识及教训

这阶段的作业,很好的体现的JAVA编程的三大特性、五大原则,相较于上一阶段,这个阶段让我们更加了解了面向对象程序设计的思想,在程序过程中要充分的理解到三大特性与五大原则,在设计程序的过程中,类与类之间最好做到独立、复用、多态。如果在编程过程中不够严谨,将会使你的程序杂乱无序,且复用性低,如果程序出错,将会带来很大的麻烦,并且程序代码在时间和空间维度都特别大,代码质量不高。

2.OO设计心得

一:对面向对象程序设计三大特性的理解

面向对象的三大特性即是:封装、继承、多态

 

封装:隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别。将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有机的结合,形成“类”,其中数据和函数都是类的成员。封装的目的是增强安全性和简化编程,使用者不必了解具体的实现细节,而只是要通过外部接口,一特定的访问权限来使用类的成员。封装的基本要求是: 把所有的属性私有化,对每个属性提供getter和setter方法,如果有一个带参的构造函数的话,那一定要写一个不带参的构造函数。在开发的时候经常要对已经编写的类进行测试,所以在有的时候还有重写toString方法,但这不是必须的。

 

继承:通过继承实现代码复用。Java中所有的类都是通过直接或间接地继承java.lang.Object类得到的。继承而得到的类称为子类,被继承的类称为父类。子类不能继承父类中访问权限为private的成员变量和方法。子类可以重写父类的方法,及命名与父类同名的成员变量。但Java不支持多重继承,即一个类从多个超类派生的能力。在开发中尽量减少继承关系,这样做是为了把程序的耦合度降低。

 

多态:多态又分为设计时多态和运行时多态,例如重载又被称为设计时多态,而对于覆盖或继承的方法,JAVA运行时系统根据调用该方法的实例的类型来决定选择调用哪个方法则被称为运行时多态。总而言之,面向对象的设计的典型特点就是继承,封装和多态,这些特点也是面向对象之所以能如此盛行的关键所在。

上述资料引自博客园博主长虹若日“JAVA 三大特性、五大原则”博客,仅供参考。

原文地址:https://www.cnblogs.com/libao/archive/2012/12/24/2831432.html。

对于三大特性的理解与之前理解面向对象程设设计的编程思想一样,都是要引用现实世界的相关例子来理解,封装的基本单位是一个类,而类就相当于现实世界的一个集体、或者一个人,每个人都是互不相干的,封闭的,只有人与人之间相互交流,才能实现类与类之间的联系,而这个就相当于面向对象程序设计中的接口。继承也要借用现实世界的自然规律来理解,子类可以访问父类的方法与属性,就像现实世界,儿子可以遗传父亲的特征等。多态也是,通过遗传父亲的特性,再对父亲的特性重新改造或者学习,实现不一样的功能,实现多态,在面向对象程序设计中,子类继承父类的方法,再对父类的方法重写或者覆盖,使这个方法实现另一种功能,实现多态。

二:面向对象设计的基本原则理解(单一职责原则及“开-闭”原则)

1、单一职责

不论是在设计类,接口还是方法,单一职责都会处处体现,单一职责的定义:我们把职责定义为系统变化的原因。所有在定义类,接口,方法的时候。定义完以后再去想一想是不能多于一个的动机去改变这个类,接口,方法。如果答案是肯定的,说明定义的类,接口,方法则多于一个职责。故违背单一职责,遇到这种情况应该重新细分职责,直到不会出现多种职责的类,接口方法为止(发现职责,并把那些职责相互分离)。单一职责的为最简单的五种原则之一。在软件设计的过程中处处体现。无处不在。

2、开闭原则

开闭原则是指类、模块、方法是可以扩展的,但不可以修改。开即对扩张开放,闭即对修改关闭。开闭原则的应用体现在,开发人员应该仅仅对程序中频繁出现变化的地方进行抽象(封装变化点)。对变化点的封装即对变化的修改关闭。对于变化的不确定性,可随时扩展。即 继承的使用。抽象类的运用。

上述资料引自博客园博主长虹若日“JAVA 三大特性、五大原则”博客,仅供参考。

原文地址:https://www.cnblogs.com/libao/archive/2012/12/24/2831432.html。

对于单一原则与开闭原则的理解,也是要结合现实世界的相关例子,再结合题目,代入情景进行理解。

三:OO编程思维的理解

我目前理解oo编程思维最主要的基本元素是类和对象,类就相当于现实世界人的一种标签,例如南昌航空大学软件学院19201512学生是15班的,是19级的,是软件学院的,是南昌航海大学的学生,诸如此类标签,oo编程思想中的类就相当于这一些标签,而对象就相当于现实世界的一个人,相当于学号19201512这个人。oo设计主要任务是将设计尽量和现实世界的事务一致化。尽量使程序设计的思路符合现实世界事务的规律。类和对象 是oo编程中最重要最基本的两个元素,在设计时,先将找到要处理的各个对象,再找到各个对象的共同的祖先,逐层抽象。最后确立各个类之间的继承关系。所有综上,我对oo的理解很大程度上类比于与现实世界,类与对象就相当于软件维度的东西。其实本质上是与现实世界一样的。并且OO编程设计很多的特性与原则都是与现实世界息息相关的,例如三大特性、五大原则,都是自然世界的一些规律,学习理解可以通过类比现实世界的一些例子与规律来进行理解,例如接口与抽象类的理解,接口是两个继承关系不强的类之间的联系,例如猪肉可以吃,苹果也可以吃,两个事物在继承关系上并不强烈甚至毫不相干,但两种事物都有吃的特性,这个吃的特性就相当于面向对象程序设计中的接口。其实OO很多编程思维都与现实世界某些自然规律息息相关,通过与现实世界类比,来更好的理解OO编程思维。

四:类设计心得

类的设计尽量做到,简单,复用性强,每个类的作用都明确切少。类的设计符合JAVA类设计的五大原则,做到独立可复用,类与类之间的关系也做到,简单明了,符合JAVA的三大特性。

3.测试的理解与实践

一:测试对于编码质量的重要性

软件的质量除了靠程序员编写时代码的正规化和代码的严谨程度之外,很重要的一环就是代码的测试,测试是什么?测试就是对开发的代码产品进行差错审查,保证代码质量的一个过程,测试是对代码对象进行审查与测试,他对于程序最终的质量起了至关重要的作用,在很多软件大厂都设有软件测试工程师这一职位,从各种角度来看,测试对于代码质量十分重要且不可缺少。

二:假设使用Junit进行程序的测试是否可行

使用Junit进行程序测试是可行的。我们在编写大型程序的时候,常常需要写千上万个方法或函数,这些函数的功能强大,但我们在程序中只用到该函数的一小部分功能,每编写完一个函数之后,我们都应该对这个函数的方方面面进行测试,这样的测试我们称之为单元测试。那么如何确保每一个方法或者函数都完全正确呢?传统的编程方式,进行单元测试是一件很麻烦的事情,你要重新写另外一个程序,在该程序中调用你需要测试的方法,并且仔细观察运行结果,看看是否有错。Junit单元测试框架是Java程序开发必备的测试利器,现在最常用的就是Junit了,在Junit 中所有的测试用例都使用了注解的形式。JUnit是一个Java语言的单元测试框架。它由Kent Beck和Erich Gamma建立,逐渐成为源于Kent Beck的sUnit的xUnit家族中最为成功的一个。 JUnit有它自己的JUnit扩展生态圈。多数Java的开发环境都已经集成了JUnit作为单元测试的工具。也就是说junit就是别人写好的单元测试框架,使用此框架可以大大缩短代码的测试时间和准确度。

4.课程收获

在这四周来,我更加的了解了OO的编程思维,了解了JAVA的三大特性、五大原则,类如何设计能够做到相对独立,复用性强,如何实现和运用接口,熟悉的掌握了正则表达式的相关知识,也了解掌握StringBulder、StringBuffer、ArrayList类的使用,以及其中一些方法的调用。也了解了实际工程中,对类设计的要求,和程序整体结构设计的要求,进一步进入了面向对象世界。

5.对课程的建议

一:第三阶段作业难度、题量的建议

难度建议不要太大,可以设计一些课外的知识,通过自学掌握,但类于类之间的关系不要太复杂,例如第五次作业第一题难度较大,第七次作业难度较合适,题量也合适。

二:课程内容讲解方面的建议

希望老师可以讲解PTA或者我们自己写过的作业,因为自己写的作业自己思考过,每个人知道自己的问题在哪里,带着问题去学习相比于课堂上的书本上的代码样例可能更能带来触动,并留下更深的印象!或者讲解题目涉及的课外知识等!

猜你喜欢

转载自www.cnblogs.com/Nchu-19201512/p/12820209.html