前言

之前所涉及知识点如下:

  类与类之间的关系、类设计的原则、一些常见的类等

  题量在可接受范围之内

正文

 第二次雨刷问题

 

 

设计与分析:

  本次我们首次使用类来编写代码,并引入了业务类和实体类的概念。我通过雨刷的功能编写了Lever、Wiper、Dial三个实体类,并编写了Control这个业务类来调控这三个实体类。通过驾驶员的信息输入编写了HandsOfDriver和EyesOfDriver两个类,目的是想做出雨刷模拟系统的感觉。

踩坑心得:

  没有深刻理解类间关系,耦合性太高。

改进建议:

   HandsOfDriver应该通过Control来和Lever、Wiper、Dial三个实体类进行交流

 

第三次雨刷问题

 

设计与分析:

  利用private对各个类进行了封装,提高了安全性。其他类与Lever、Wiper、Dial三个实体类不再是直接交流,而通过Control这个媒介,使得结构更加严谨,便于以后维护和更新。

踩坑心得:

  Main中包含的内容太多了,而且Control只将一部分类联系起来了。

改进建议:

   将Main中的的功能转移到Control中,将更多类通过Control联系起来。

 

 第四次雨刷问题

 

 

设计与分析:

  本次尝试用单例模式来避免重复创建对象的行为,此处我用的是懒汉模式。

踩坑心得:

  前期没有理解单例模式的意义和使用,绕了很多弯子;没有注意线程的安全性,并发性差。

改进建议:

   在方法上加锁或对类对象加锁。

 

第五次雨刷问题

 

 

设计与分析:

  本次采用继承来增强代码的扩展性。我设计了Driver、Dial、Brush、Lever、Control五个抽象父类来初步得确立了各个类基本的方法,之后我设计了DriverType1、DialType1、BrushType1、LeverType1、ControlType1作为其子类,并对父类的抽象方法进行了重写,同时也为了各个类的扩展提供了可能性。

踩坑心得:

  一开始没有将super放在第一句导致报错

改进建议:

   设计更多不同种类的子类来加深对继承意义的理解

 

PTA题目集

设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1820,2020] ,month∈[1,12] ,day∈[1,31] , 设计类图如下:

 

设计与分析:

  此题给出了相关类图,限制了做题空间。Day、Year、Month作为成员变量存在于DateUtil中,因此Day、Year、Month与DateUtil是聚合关系。我的思路是先编写Day、Year、Month这几个实体类,各个击破,因为Day、Year、Month这几个实体类之间的联系不大。之后编写DateUtil,将Day、Year、Month这几个实体类联系起来。

踩坑心得:

  没有进行边界值测试,如月初、月底、年初、年底,导致几个点迟迟过不了。

改进建议:

   下次不仅要测试题目中给的例子,也要通过其他不同的数值进行测试,精准找到问题之所在。

 

 PTA题目集

本程序仅用于为学生所玩的游戏提供正确答案的功能,即根据学生得到的卡片种类与数量,给出 排序前和排序后的卡片顺序,同时给出所有卡片的面积之和。

 

 

 

设计与分析:

  此题给出了相关类图,限制了做题空间。整个结构层层推进,Shape是一个抽象父类,Trapezoid、Triangle、Rectangle、Circle 是 Shape 的子类。我首先从Shape入手,再编写Trapezoid、Triangle、Rectangle、Circle 类,再一层一层往上逆推,最终完成整个架构的建立。

踩坑心得:

  一开始并没有考虑到CompareTo这个接口的作用

改进建议:

   要学会读懂类图,并从整体上设计类

 

 

总结

知识点:

MVC设计模式,即M:Model (实体类,Entity)、V:View (接口类,GUI)、C:Controller (控制类,Control)

 

类与类的关系:

  依赖关系(Dependency)、关联关系(Association)、聚合关系(Aggregation)、组合关系(Composition)、继承关系(泛化关系 Generalization)、实现关系(Realization)

  区分类与类之间的关系:要从语义上而不是语法上。

  耦合性强弱:组合 > 聚合 > 关联 > 依赖

 

继承关系:

   class 子类 extends 父类 {}

  super:

  1.子类想用到父类的东西时,需要用到super.   

  2.在子类构造方法的第一行(只能)用super()调用父类对应的构造方法为了创建子类对象时,先初始化父类型特征

  abstract抽象类:

  抽象类不能实例化对象,抽象方法需要在子类中@Override复写。如果名称不一致 也没有写override 则会在不报错

 

类的设计原则:

  单一职责原则:一个类只负责一项职责

  迪米特法则:1.不要和陌生人说话(实体类之间一般都是陌生人) 2.只和你的直接朋友通信  3.最少知识原则

  里氏替换原则:子类可以扩展父类的功能,但不能改变父类原有的功能

  合成复用原则:在软件复用时,要尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现

  依赖倒置原则:要依赖抽象,不要依赖具体 要依赖接口,不要依赖编程

  开闭原则:一个软件实体如类,模块和函数应该对扩展开放,对修改关闭

  接口隔离原则:一个接口里的方法越少越好(所以一个接口就一个方法)

 

 

接口:

 

  public interface 父类{}

 

  class 子类 implements 父类1,父类2...{}

 

  应用场合:对于行为/方法的抽象,区别抽象类(对于实体的抽象)

 

  特点:支持多继承

 

  2.容器

 

  (1)Array

 

    String[] array = {}

 

    //输出

 

    for(String data:array){

 

      Systrm.out.print(data + "  ");

 

     }

 

    System.out.println("")

 

    //排序(升序)

 

    java.util.Arrays.sort(array);

 

  (2)list

 

    定义:ArrayList list = new ArrayList();//查找数据时用    LinkedList list = new LinkedList();//增删时用

 

    泛型:把类型做参数 LinkedList<Integer> list = new LinkedList()<Integer>;

 

    输出:for(int i = 0; i < list.size();i ++){ }

 

     //排序(升序)

    java.util.Collections.sort(list1);

    列表中是实型,整型,字符串可用

    若类列表要用,要调用方法

    java.util.Collections.sort()

 

  (3)String StringBuffer StringBuilder

 

    字符串连接效率: StringBuilder > StringBuffer > String

 

    涉及变长字符串用StringBuilder、StringBuffer,在涉及多线程用StringBuffer

    System.out.println(str1==str3)->true//地址相同

    System.out.println(str2==str3)->true

    String Builder sb1 = new StringBuilder("abc");

    sb1.append("123")

    System.out.println(sb1.toString());->abc123//转成字符串输出

 

 

八种基本变量类型:

 

  int long short char float double byte boolean

 

 

一些修饰符:

 

  private public protected default static final(不能继承) abstract class interface extends implements Object(Object类是所有类的父类) this super 

 

 

测试方法/技术:

 

  1.边界值测试

 

  程序的缺陷往往容易发生在输入数据的边界

 

  健壮性边界值测试

 

  2.等价类测试

 

  等价关系:自反关系、反对称关系、传递关系

 

  划分子集的依据就是等价关系,之后的子集叫做等价 

 

类的设计原则:

  简单工厂模式、工厂方法模式、抽象工厂模式等

 

多态:

  不同的对象接收到同一消息产生不同的操作

  1.Circle circle = new Circle("black",3.24);

  2.Circle.getArea();

  3.hape shape = new Circle(); 子类的对象赋给父类类型是可行的

  4.System.out.println(shape.getArea());

  5.Shape = new Ball("BLACK", 5.4);

  6.System.out.println(shape.getArea());

  第四行与第六行 两段相同的代码 输出的结果不同

 

部分代码如下:

 

import java.util.Scanner;

 

public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int year = 0;
int month = 0;
int day = 0;

 

int choice = input.nextInt();

 

if (choice == 1) { // test getNextNDays method
int m = 0;
year = Integer.parseInt(input.next());
month = Integer.parseInt(input.next());
day = Integer.parseInt(input.next());

 

DateUtil date = new DateUtil(year, month, day);

 

if (!date.checkInputValidity()) {
System.out.println("Wrong Format");
System.exit(0);
}

 

m = input.nextInt();

 

if (m < 0) {
System.out.println("Wrong Format");
System.exit(0);
}

 

System.out.print(date.getYear().getValue() + "-" + date.getMonth().getValue() + "-" + date.getDay().getValue() + " next " + m + " days is:");
System.out.println(date.getNextNDays(m).showDate());
} else if (choice == 2) { // test getPreviousNDays method
int n = 0;
year = Integer.parseInt(input.next());
month = Integer.parseInt(input.next());
day = Integer.parseInt(input.next());

 

DateUtil date = new DateUtil(year, month, day);

 

if (!date.checkInputValidity()) {
System.out.println("Wrong Format");
System.exit(0);
}

 

n = input.nextInt();

 

if (n < 0) {
System.out.println("Wrong Format");
System.exit(0);
}

 

System.out.print(
date.getYear().getValue() + "-" + date.getMonth().getValue() + "-" + date.getDay().getValue() + " previous " + n + " days is:");
System.out.println(date.getPreviousNDays(n).showDate());
} else if (choice == 3) { //test getDaysofDates method
year = Integer.parseInt(input.next());
month = Integer.parseInt(input.next());
day = Integer.parseInt(input.next());

 

int anotherYear = Integer.parseInt(input.next());
int anotherMonth = Integer.parseInt(input.next());
int anotherDay = Integer.parseInt(input.next());

 

DateUtil fromDate = new DateUtil(year, month, day);
DateUtil toDate = new DateUtil(anotherYear, anotherMonth, anotherDay);

 

if (fromDate.checkInputValidity() && toDate.checkInputValidity()) {
System.out.println("The days between " + fromDate.showDate() +
" and " + toDate.showDate() + " are:"
+ fromDate.getDaysofDates(toDate));
} else {
System.out.println("Wrong Format");
System.exit(0);
}
}
else{
System.out.println("Wrong Format");
System.exit(0);
}
}
}

 


class DateUtil {
private Year year = new Year();
private Month month = new Month();
private Day day = new Day();
private int[] mon_maxnum = { 31,28,31,30,31,30,31,31,30,31,30,31};

public DateUtil() {
}

public DateUtil(int y, int m, int d) {
this.year.setValue(y);
this.month.setValue(m);
this.day.setValue(d);
}

 

public Year getYear() {
return year;
}

 

public void setYear(Year year) {
this.year = year;
}

 

public Month getMonth() {
return month;
}

 

public void setMonth(Month month) {
this.month = month;
}

 

public Day getDay() {
return day;
}

 

public void setDay(Day d) {
this.day = day;
}

public void setDayMin() {
this.day.setValue(1);
}

public void setDayMax() {
if(this.year.isLeapYear(this.month.getValue())) {
mon_maxnum[1] = 29;
}
this.day.setValue(mon_maxnum[this.month.getValue()-1]);
mon_maxnum[1] = 28;
}

public boolean checkInputValidity() {
boolean validate0;
if(year.isLeapYear(year.getValue())) {
mon_maxnum[1] = 29;
}
if(this.month.getValue() >= 1 && this.month.getValue() <= mon_maxnum[this.month.getValue() - 1]) {
validate0 = true;
}
else {
validate0 = false;
}
mon_maxnum[1] = 28;

boolean validate1 = false;
if(validate0 && this.month.validate() && this.year.validate()) {
validate1 = true;
}
return validate1;
}

public boolean compareDates(DateUtil date) {
boolean compare = false;
if(this.year.getValue() < date.year.getValue()) {
compare = true;
}
else if(this.year.getValue() == date.year.getValue()){
if(this.month.getValue() < date.month.getValue()) {
compare = true;
}
else if(this.month.getValue() == date.month.getValue()) {
if(this.day.getValue() < date.day.getValue()) {
compare = true;
}
}
}
return compare;
}

public boolean equalTwoDates(DateUtil date) {
boolean equal = false;
if(this.year.getValue() == date.year.getValue() && this.month.getValue() == date.month.getValue() && this.day.getValue() == date.day.getValue()) {
equal = true;
}
return equal;
}

public String showDate() {
return this.year.getValue() + "-" + this.month.getValue() + "-" + this.day.getValue();
}

public DateUtil getNextNDays(int n) {
int year = this.year.getValue(), month = this.month.getValue(), day = this.day.getValue();
int[] monthTable= { 31,28,31,30,31,30,31,31,30,31,30,31};
if(this.year.isLeapYear(year)) {
monthTable[1]=29;
}
day += n;
if(n>monthTable[month-1]-day) {
do{
day -= monthTable[month-1];
month++;
if(month>12) {
month = 1;
year++;
if(this.year.isLeapYear(year)) {
monthTable[1]=29;
}
else {
monthTable[1]=28;
}
}
}while(day>monthTable[month-1]);
}
return new DateUtil(year,month,day);
}

public DateUtil getPreviousNDays(int n) {
int year = this.year.getValue(), month = this.month.getValue(), day = this.day.getValue();
int[] monthTable= { 31,28,31,30,31,30,31,31,30,31,30,31};
if(this.year.isLeapYear(year)) {
monthTable[1]=29;
}
day -= n;
while(day<=0) {
if(month==1) {
month = 12;
year--;
if(this.year.isLeapYear(year)) {
monthTable[1]=29;
}
else {
monthTable[1]=28;
}
day += monthTable[11];

}
else {
day += monthTable[month-2];
month --;
}
}
return new DateUtil(year,month,day);
}

public int getDaysofDates(DateUtil date) {
DateUtil i = this;
int n = 0;
if(equalTwoDates(date)) {
}
else {
if(compareDates(date)) {
while(i.year.getValue() != date.year.getValue() || i.month.getValue() != date.month.getValue() || i.day.getValue() != date.day.getValue()){
n++;
i = getNextNDays(n);
}
}
else {
while(i.year.getValue() != date.year.getValue() || i.month.getValue() != date.month.getValue() || i.day.getValue() != date.day.getValue()){
n++;
i = getPreviousNDays(n);

}
}
}
return n;
}

}

 


class Day {
private int value;

 

public Day() {
}

public Day(int Value) {
this.value = Value;
}

 

public int getValue() {
return value;
}

 

public void setValue(int value) {
this.value = value;
}

 

public void dayIncrement() {
this.value++;
}

public void dayReduction() {
this.value--;
}

}

 


class Month {
private int value;

public Month() {
}

public Month(int Value) {
this.value = Value;
}

 

public int getValue() {
return value;
}

 

public void setValue(int value) {
this.value = value;
}

public void resetMin() {
this.value = 1;
}
public void resetMax() {
this.value = 12;
}

public boolean validate() {
boolean validate;
if(value>=1&&value<=12) {
validate=true;
}
else {
validate=false;
}
return validate;
}

public void monthIncrement() {
this.value++;
}

public void monthReducton() {
this.value--;
}

}

 


class Year {
private int value;

public Year() {
}

public Year(int value) {
this.value = value;
}

 

public int getValue() {
return value;
}

public void setValue(int value) {
this.value = value;
}

public boolean isLeapYear(int year) {
boolean isLeapYear;
if(year%400==0)
isLeapYear=true;
else
{
if(year%4==0)
{
if(year%100!=0)
isLeapYear=true;
else
isLeapYear=false;
}
else
isLeapYear=false;
}
return isLeapYear;
}

public boolean validate() {
boolean validate = false;
if(value >= 1820 && value <= 2020) {
validate = true;
}
return validate;
}

public void yearIncrement() {
this.value++;
}

public void yearReduction() {
this.value--;
}
}

 

posted on 2022-04-13 21:33  不知明月照何人  阅读(50)  评论(0)    收藏  举报