1-5周阶段性总结(修正)
1、前言
最近五周PTA和超星上的作业所涉及到的知识点主要有以下:
类和对象的创建、类之间的关系、正则表达式、字符串的操作处理、类的设计以及七大原则、关键字。
类的创建包括类的属性,类的构造方法、类的方法。
类的属性一般设置为private(私有的)只有类内可以访问,类内用this.来引用属性,若用public(公有的)则属性可能在类外被修改,这会使其不安全。
类的构造方法一般有两个,一个无参的构造方法,一个有参的构造方法,若类没有属性,则只有一个无参的构造方法。
类的方法一般为public,一般的,每个属性都有一个对应的get方法和一个对应的set方法,用于修改和得到作为private的属性。
类之间的关系包括关联、组合、聚合、依赖、继承、实现。
关联:就是对象之间有关系,则可称为关联。用带箭头的实线,箭头指向被关联类,实线起始端是关联类。
组合:类之间有整体和部分的关系,并且拥有统一的生存期,一旦整体对象不存在,则部分对象也不存在,整体类可以控制成员类的生存周期。用带实心菱形的有箭头实线,实心菱形为整体,箭头指向部分。
聚合:类之间也有整体和部分的关系,但没有统一的生存期,整体对象不能存在了,部分对象也仍可以存在。用带空心菱形的有箭头的实线,空心菱形指向整体类,箭头指向成员类。
依赖:表示一个事务需要使用另一个事务。例如类A中某个方法的形参是类B类型;类A中某个方法的返回类型是类B类型。类A中某个方法中的局部变量是类B类型。用带箭头的虚线,箭头指向被依赖类,虚线起始端为依赖类。
继承:也叫做泛化,指一个类(称为子类、子接口)继承另外的一个类(称为父类、父接口),子类增加新功能。是实现多态的重要办法。用带空心三角形的实线,空心三角形指向父类,实线开始端为子类。
实现:某个类实现另一个接口类,用带空心三角形的虚线,空心三角形指向接口,虚线开始端为类。
正则表达式是对字符串操作的一种逻辑公式,通常被用来检索、替换那些符合某个模式(规则)的文本。先设计匹配规则,再用函数来匹配,若符合则返回true否则返回false。
字符串的操作处理
获取长度:length()方法
获取第i个位置的字符:charAt(i)方法
字符串大小比较(比较的是字母顺序):不忽略大小写compareTo(str)。忽略大小写compareTolgnoreCase(str)。
字符串是否相等:不忽略大小写equals(str)。忽略大小写equalslgnoreCase(str)。
字符串查找:indexOf(ch或str)方法,返回第一次出现的位置。iastindexOf()方法,返回最后一次出现的位置。
字符串的拆分:split()方法。split(正则表达式)。
字符串的截取:substring()方法,可以截取出范围内的字符串。
字符串的替换:concat()方法合并字符串, toLowerCase()方法 将字符全部转化为小写,toUpperCase()方法 将字符全部转化为大写,replaceAll()、replaceFirst()方法需要匹配正则表达式。
类的设计以及七大设计原则
类的设计应该使类之间的耦合度降低,提高代码的可读性,可复用性,可维护性和可扩展性。
七大设计原则:
单一职责原则:一个类应该只负责一个原则。
接口分离原则:不要把方法都放在一个接口类里面,而应该把方法分隔开放在不同的接口里面,甚至可以使一个接口类里面只有一个方法,这样可以使依赖他的类没有多余方法。
依赖倒置原则:高层模块不应该依赖低层模块,二者都应该依赖其抽象,抽象不应该依赖细节,细节应该依赖抽象。中心思想是面向接口编程。
里氏替换原则:子类应该有父类所有的方法,能够替换父类的类型。
开闭原则:类的模块和函数应该对扩展开放,对修改关闭,修改软件时应该尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化。
迪米特法则:一个对象应该对其他的对象保持最少的了解,类与类关系越密切,耦合度越大,一个类对自己依赖的类知道的越少越好,每个对象只与直接朋友打交道,不与陌生人打交道。
合成复用原则:尽量使用组合和聚合而不是用继承。
关键字
public 和private abstract 用于类和方法
private 只能在类内进行访问,pulibc则只需要类在一个包内就可以实现类外访问。
abstract则表明类是抽象类或方法是抽象方法。
this 和super
this用于调用类内的属性,super用来调用父类的属性或构造方法
extends用于子类表明继承于某个类
implements表明一个类实现了给定的接口
import 引入类或包
static表明静态属性
最近五周PTA和超星上的作业题量适中,难度为前期较为简单,后期较为困难。
2、设计与分析
PTA题目集01日期问题面向对象设计(聚合一)需要设计如下几个类DateUtil、Year、Month、Day,类图如下
Year类依赖于Month类,Month类依赖于Day类,Day类依赖于DateUtil类,这是一种层层包含的关系,再DateUtil类中的compareDates()方法中参数也需要通过DateUtil的对象一层一层的传递最后来得到每个Year、Month、Day对象的Value值。
而日期问题面向对象设计(聚合二)类图如下
则是DateUtil类依赖于Year类和Month类还有Day类,DateUtil类中的compareDates()方法则不需要一层一层传递,直接将Year类和Month类以及Day类作为自己的属性,直接用getter和setter方法来获取Year类对象、Month类对象以及Day类对象的Value值。
雨刷问题5设计了三个抽象类Lever类、Control类、Dial类,分别各有两个子类,例如Lever1类和Lever2类,子类之间并不打交道,而是通过父类之间来打交道,程序实现了可以使用两种模式的雨刷。类图如下
Driver类负责决定进行哪种操作,Print类负责输出目前控制杆,刻度盘,雨刷的状态。
3、踩坑心得
在进行PTA01题目集日期设计(聚合一)时,当时还不太会一层一层的传递,不懂如何通过DateUtil类一步步得到Year类中的Value属性,解决问题后才知道原来时通过get返回对象的方法,一步一步得到最终所要的东西。
例如以下代码中的this.day.getMonth().getYear().getValue()就通过DateUtil的对象来得到了对应的年份。
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(day, month, year);
if (date.checkInputValidity()==false) {
System.out.println("Wrong Format");
System.exit(0);
}
m = input.nextInt();
if (m < 0) {
System.out.println("Wrong Format");
System.exit(0);
}
date=date.getNextDays(m);
System.out.println(date.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(day, month, year);
if (date.checkInputValidity()==false) {
System.out.println("Wrong Format");
System.exit(0);
}
n = input.nextInt();
if (n < 0) {
System.out.println("Wrong Format");
System.exit(0);
}
date=date.getPreviousNDays(n);
System.out.println(date.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(day, month, year);
DateUtil toDate = new DateUtil(anotherDay, anotherMonth, anotherYear);
if (fromDate.checkInputValidity()==true && toDate.checkInputValidity()==true) {
System.out.println(fromDate.getDaysofDates(toDate));
} else {
System.out.println("Wrong Format");
System.exit(0);
}
}
else{
System.out.println("Wrong Format");
System.exit(0);
}
}
}
class DateUtil {
private Day day=new Day();
public DateUtil() {
// TODO Auto-generated constructor stub
}
public DateUtil(int d,int m,int y) {
this.day.setValue(d);
this.day.getMonth().setValue(m);
this.day.getMonth().getYear().setValue(y);
}
public Day getDay() {
return this.day;
}
public void setDay(Day d) {
this.day=d;
}
public boolean checkInputValidity() {
if(this.day.getValue()<1||this.day.getValue()>31) {
return false;
}
if(this.day.getMonth().getValue()<1||this.day.getMonth().getValue()>12) {
return false;
}
if(this.day.getMonth().getYear().getValue()<1900||this.day.getMonth().getYear().getValue()>2050) {
return false;
}
if(this.day.getMonth().getValue()==2&&this.day.getMonth().getYear().isLeapYear()==false&&this.day.getValue()>28) {
return false;
}
if(this.day.getMonth().getValue()==2&&this.day.getMonth().getYear().isLeapYear()==true&&this.day.getValue()>29) {
return false;
}
if((this.day.getMonth().getValue()==4||this.day.getMonth().getValue()==6||this.day.getMonth().getValue()==9||this.day.getMonth().getValue()==11)&&this.day.getValue()>30) {
return false;
}
else {
return true;
}
}
public boolean compareDates(DateUtil date) {
if(this.day.getMonth().getYear().getValue()>date.day.getMonth().getYear().getValue()) {
return true;
}
else if(this.day.getMonth().getYear().getValue()<date.day.getMonth().getYear().getValue()) {
return false;
}
else {
if(this.day.getMonth().getValue()>date.day.getMonth().getValue()) {
return true;
}
else if(this.day.getMonth().getValue()<date.day.getMonth().getValue()) {
return false;
}
else {
if(this.day.getValue()>date.day.getValue()) {
return true;
}
else if(this.day.getValue()<date.day.getValue()) {
return false;
}
else {
return false;
}
}
}
}
public boolean equalTwoDates(DateUtil date) {
if(this.day.getValue()==date.day.getValue()&&this.day.getMonth().getValue()==date.day.getMonth().getValue()&&this.day.getMonth().getYear().getValue()==date.day.getMonth().getYear().getValue()) {
return true;
}
else {
return false;
}
}
public String showDate() {
return this.day.getMonth().getYear().getValue()+"-"+this.day.getMonth().getValue()+"-"+this.day.getValue();
}
public DateUtil getNextDays(int n) {
DateUtil dateutil=new DateUtil(this.day.getValue(),this.day.getMonth().getValue(),this.day.getMonth().getYear().getValue());
while(n>=146097){
dateutil.day.getMonth().getYear().setValue(dateutil.day.getMonth().getYear().getValue()+400);
n=n-146097;
}
while(n>=1){
if((dateutil.day.getMonth().getValue()==1||dateutil.day.getMonth().getValue()==3||dateutil.day.getMonth().getValue()==5||dateutil.day.getMonth().getValue()==7||dateutil.day.getMonth().getValue()==8||dateutil.day.getMonth().getValue()==10)&&dateutil.day.getValue()==31||(dateutil.day.getMonth().getValue()==4||dateutil.day.getMonth().getValue()==6||dateutil.day.getMonth().getValue()==9||dateutil.day.getMonth().getValue()==11)&&dateutil.day.getValue()==30)
{
dateutil.day.getMonth().setValue(dateutil.day.getMonth().getValue()+1);
dateutil.day.setValue(1);
}
else if(dateutil.day.getMonth().getValue()==2&&dateutil.day.getMonth().getYear().isLeapYear()==false&&dateutil.day.getValue()==28)
{
dateutil.day.getMonth().setValue(dateutil.day.getMonth().getValue()+1);
dateutil.day.setValue(1);
}
else if(dateutil.day.getMonth().getValue()==2&&dateutil.day.getMonth().getYear().isLeapYear()==true&&dateutil.day.getValue()==29){
dateutil.day.getMonth().setValue(dateutil.day.getMonth().getValue()+1);
dateutil.day.setValue(1);
}
else if(dateutil.day.getMonth().getValue()==12&&dateutil.day.getValue()==31)
{
dateutil.day.getMonth().getYear().setValue(dateutil.day.getMonth().getYear().getValue()+1);
dateutil.day.getMonth().setValue(1);
dateutil.day.setValue(1);
}
else
{
dateutil.day.setValue(dateutil.day.getValue()+1);
}
n--;
}
return dateutil;
}
public DateUtil getPreviousNDays(int n) {
DateUtil dateutil=new DateUtil(this.day.getValue(),this.day.getMonth().getValue(),this.day.getMonth().getYear().getValue());
while(n>=146097){
dateutil.day.getMonth().getYear().setValue(dateutil.day.getMonth().getYear().getValue()-400);
n=n-146097;
}
while(n>=1){
if((dateutil.day.getMonth().getValue()==5||dateutil.day.getMonth().getValue()==7||dateutil.day.getMonth().getValue()==10||dateutil.day.getMonth().getValue()==12)&&dateutil.day.getValue()==1)
{
dateutil.day.getMonth().setValue(dateutil.day.getMonth().getValue()-1);
dateutil.day.setValue(30);
n--;
}
else if((dateutil.day.getMonth().getValue()==2||dateutil.day.getMonth().getValue()==4||dateutil.day.getMonth().getValue()==6||dateutil.day.getMonth().getValue()==8||dateutil.day.getMonth().getValue()==9||dateutil.day.getMonth().getValue()==11)&&dateutil.day.getValue()==1)
{
dateutil.day.getMonth().setValue(dateutil.day.getMonth().getValue()-1);
dateutil.day.setValue(31);
n--;
}
else if(dateutil.day.getMonth().getValue()==1&&dateutil.day.getValue()==1)
{
dateutil.day.getMonth().getYear().setValue(dateutil.day.getMonth().getYear().getValue()-1);
dateutil.day.getMonth().setValue(12);
dateutil.day.setValue(31);
n--;
}
else if(dateutil.day.getMonth().getValue()==3&&dateutil.day.getMonth().getYear().isLeapYear()==true&&dateutil.day.getValue()==1)
{
dateutil.day.getMonth().setValue(dateutil.day.getMonth().getValue()-1);
dateutil.day.setValue(29);
n--;
}
else if(dateutil.day.getMonth().getValue()==3&&dateutil.day.getMonth().getYear().isLeapYear()==false&&dateutil.day.getValue()==1)
{
dateutil.day.getMonth().setValue(dateutil.day.getMonth().getValue()-1);
dateutil.day.setValue(28);
n--;
}
else
{
dateutil.day.setValue(dateutil.day.getValue()-1);
n--;
}
}
return dateutil;
}
public int getDaysofDates(DateUtil date){
int amount=0;
if(this.compareDates(date)==true){
while(this.equalTwoDates(date)==false){
if((this.day.getMonth().getValue()==5||this.day.getMonth().getValue()==7||this.day.getMonth().getValue()==10||this.day.getMonth().getValue()==12)&&this.day.getValue()==1){
this.day.getMonth().setValue(this.day.getMonth().getValue()-1);
this.day.setValue(30);
amount++;
}
else if((this.day.getMonth().getValue()==2||this.day.getMonth().getValue()==4||this.day.getMonth().getValue()==6||this.day.getMonth().getValue()==8||this.day.getMonth().getValue()==9||this.day.getMonth().getValue()==11)&&this.day.getValue()==1) {
this.day.getMonth().setValue(this.day.getMonth().getValue()-1);
this.day.setValue(31);
amount++;
}
else if(this.day.getMonth().getValue()==1&&this.day.getValue()==1) {
this.day.getMonth().getYear().setValue(this.day.getMonth().getYear().getValue()-1);
this.day.getMonth().setValue(12);
this.day.setValue(31);
amount++;
}
else if(this.day.getMonth().getValue()==3&&this.day.getValue()==1&&this.day.getMonth().getYear().isLeapYear()==true) {
this.day.getMonth().setValue(this.day.getMonth().getValue()-1);
this.day.setValue(29);
amount++;
}
else if(this.day.getMonth().getValue()==3&&this.day.getValue()==1&&this.day.getMonth().getYear().isLeapYear()==false) {
this.day.getMonth().setValue(this.day.getMonth().getValue()-1);
this.day.setValue(28);
amount++;
}
else{
this.day.setValue(this.day.getValue()-1);
amount++;
}
}
return amount;
}
else {
while(this.equalTwoDates(date)==false) {
if((this.day.getMonth().getValue()==1||this.day.getMonth().getValue()==3||this.day.getMonth().getValue()==5||this.day.getMonth().getValue()==7||this.day.getMonth().getValue()==8||this.day.getMonth().getValue()==10)&&this.day.getValue()==31||(this.day.getMonth().getValue()==4||this.day.getMonth().getValue()==6||this.day.getMonth().getValue()==9||this.day.getMonth().getValue()==11)&&this.day.getValue()==30||this.day.getMonth().getValue()==2&&this.day.getMonth().getYear().isLeapYear()==true&&this.day.getValue()==29||this.day.getMonth().getValue()==2&&this.day.getMonth().getYear().isLeapYear()==false&&this.day.getValue()==28)
{
this.day.getMonth().setValue(this.day.getMonth().getValue()+1);
this.day.setValue(1);
amount++;
}
else if(this.day.getMonth().getValue()==12&&this.day.getValue()==31)
{
this.day.getMonth().getYear().setValue(this.day.getMonth().getYear().getValue()+1);
this.day.getMonth().setValue(1);
this.day.setValue(1);
amount++;
}
else
{
this.day.setValue(this.day.getValue()+1);
amount++;
}
}
return amount;
}
}
}
class Day {
private int value;
private Month month=new Month();
private int[] mon_maxnum= {31,28,31,30,31,30,31,31,30,31,30,31};
public Day() {
// TODO Auto-generated constructor stub
}
public Day(int yearValue,int monthValue,int dayValue) {
this.value=dayValue;
this.month.setValue(monthValue);
this.month.getYear().setValue(yearValue);
}
public int getValue() {
return this.value;
}
public void setValue(int value) {
this.value=value;
}
public Month getMonth() {
return this.month;
}
public void setMonth(Month value) {
this.month=value;
}
public void resetMin() {
this.value=1;
}
public void resetMax() {
this.value=mon_maxnum[this.month.getValue()-1];
}
public boolean validate() {
if(this.month.getValue()==1||this.month.getValue()==3||this.month.getValue()==5||this.month.getValue()==7||this.month.getValue()==8||this.month.getValue()==10||this.month.getValue()==12&&this.value>31||this.value<1) {
return false;
}
if(this.month.getValue()==4||this.month.getValue()==6||this.month.getValue()==9||this.month.getValue()==11&&this.value<1||this.value>30) {
return false;
}
if(this.month.getValue()==2&&this.month.getYear().isLeapYear()==true&&this.value>29||this.value<1) {
return false;
}
if(this.month.getValue()==2&&this.month.getYear().isLeapYear()==false&&this.value<1||this.value>28) {
return false;
}
else {
return true;
}
}
public void dayIncrement() {
this.value++;
}
public void dayReduction() {
this.value--;
}
}
class Month {
private int value;
private Year year=new Year();
public Month() {
// TODO Auto-generated constructor stub
}
public Month(int yearValue,int monthValue) {
this.value=monthValue;
this.year.setValue(yearValue);
}
public int getValue() {
return this.value;
}
public void setValue(int value) {
this.value=value;
}
public Year getYear() {
return this.year;
}
public void setYear(Year year) {
this.year=year;
}
public void resetMin() {
this.value=1;
}
public void resetMax() {
this.value=12;
}
public boolean validate() {
if(this.value<1||this.value>12) {
return false;
}
else {
return true;
}
}
public void monthIncrement() {
this.value++;
}
public void monthReduction() {
this.value--;
}
}
class Year {
private int value;
public Year() {
// TODO Auto-generated constructor stub
}
public Year(int value) {
this.value=value;
}
public int getValue() {
return this.value;
}
public void setValue(int value) {
this.value=value;
}
public boolean isLeapYear() {
if(this.value%4==0&&this.value%100!=0||this.value%400==0) {
return true;
}
else {
return false;
}
}
public boolean validate() {
if(this.value<1900||this.value>2050) {
return false;
}
else {
return true;
}
}
public void yearIncrement() {
this.value++;
}
public void yearReduction() {
this.value--;
}
}
在PTA题目集02中许多题目都需要用float来定义数据,而不能用double,否则会出现错误。
例如
import java.util.Scanner;
public class Main {
public Main() {
// TODO Auto-generated constructor stub
}
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
float n=in.nextFloat();
float lastGuess=in.nextFloat();
float nextGuess=0;
if(n<0||lastGuess<=0){
System.out.println("Wrong Format");
}
else{
nextGuess = (lastGuess+n/lastGuess)/2;
while(lastGuess-nextGuess>0.00001 || lastGuess-nextGuess<-0.00001){
lastGuess=nextGuess;
nextGuess = (lastGuess+n/lastGuess)/2;
}
System.out.print(lastGuess);
}
}
}
其中参数n、lastGuess、nextGuess应该用float而不是用double
4、改进建议
PTA题目集02中许多题目数据采用的都是float类型,用double类型的话会有错误,建议数据设置因该更加的合理一些,应该设置成常规的double类型。有些题目中给出的类图有一些多余的方法根本就没有用到,建议可以删减掉。
5、总结
本阶段学会了类和对象、类与类之间的关系、java七大设计原则、一些基本的关键字、泛型容器以及尝试运用过配置文件来修改参数、java三大特性封装、继承、多态。
对泛型容器的相关知识还需要进一步的学习和研究,希望老师能够多讲一些教材和慕课上之外的东西,希望课程能够更加紧凑一点,作业可以适当的增加一点,实验可以稍微频繁一点,上课时可以增加一点互动,使课堂更加的有趣一点,并且可以分配小组,一起完成任务,增加同学们的积极性。