Blog總結02(4~6次作業總結)

Blog總結02(4~6次作業總結)

1.前言

(1)題目集04共有三道題目,第一題難度較大,第二題和第三題難度適中,第一題考察的知識點是 Java 中的字元串處理類以及正則表達式對輸入字元串數據進行合法性校驗及計算,難度較大。第二題考察對日期的處理,熟悉面向對象的學習,創建多個類,然後將其中一個類的創建的對象黨當作另一個對象的屬性,考察了在其他類中創建對象和調用其他類的方法,含參數不含參數的構造方法,getset的構造方法的使用,屬性私有性的知識點等,第三題是圖形繼承題目,難度適中,考察了繼承的知識點,弄清楚子類父類的關係,子類調用父類的方法,在子類中重寫父類的方法等知識點。

(2)題目集05共有五道題目,1~3題較為簡單,分別考察對字元串的處理,對數組的處理,對整型數據排序,第四題難度較大,統計Java程式中關鍵詞的出現次數,知識點為利用正則表達式對字元進行匹配以及對字元串的處理,第五題難度適中,考察了在其他類中創建對象和調用其他類的方法,含參數不含參數的構造方法,getset的構造方法的使用,屬性私有性的知識點等,和題目集04第二題很相似但有一些區別。

(3)題目集06共有六道題目,其中1~4題較為簡單,1,3,4題考察了利用正則表達式去匹配字元串,2題考察了字元串與字元之間的轉換,以及排序,第五六題難度適中,第五題考察了類的繼承、多態性及其使用方法,讓我們了解抽象類和抽象方法,抽像類方法的調用等,還有一些ArrayList類和Collection類的使用,第六題知識點為介面的使用和類的多態性,用介面去調用方法實現功能。

2.設計與分析

(1)題目集04(7-2 )&&題目集05(7-5)

日期問題面向對象設計

應用程式共測試三個功能:

  1. 求下n天
  2. 求前n天
  3. 求兩個日期相差的天數

輸入格式:

有三種輸入方式(以輸入的第一個數字劃分[1,3]):

  • 1 year month day n //測試輸入日期的下n天
  • 2 year month day n //測試輸入日期的前n天
  • 3 year1 month1 day1 year2 month2 day2 //測試兩個日期之間相差的天數

輸出格式:

  • 當輸入有誤時,輸出格式如下: Wrong Format

  • 當第一個數字為1且輸入均有效,輸出格式如下:

    year-month-day

  • 當第一個數字為2且輸入均有效,輸出格式如下:

    year-month-day

  • 當第一個數字為3且輸入均有效,輸出格式如下:

    天數值

題目集04(7-2)源碼如下:

  1 import java.util.Scanner;
  2 
  3 public class Main {
  4 
  5     public static void main(String[] args) {
  6         Scanner input = new Scanner(System.in);
  7         int n = input.nextInt();
  8         if(n >= 1 && n <= 3) {
  9             int x = input.nextInt();
 10             int y = input.nextInt();
 11             int z = input.nextInt();
 12             DateUtil date = new DateUtil(x,y,z);
 13             
 14             if(y>12||y<1)
 15                 System.out.println("Wrong Format");
 16             else {
 17             if(date.checkInputValidity()) {
 18                 switch(n) {
 19                 case 1:
 20                     date.getNextNdate(input.nextInt());
 21                     System.out.println(date.showDate());
 22                     break;
 23                 case 2:
 24                     date.getPreviousNDays(input.nextInt());
 25                     System.out.println(date.showDate());
 26                     break;
 27                 case 3:
 28                     int a = input.nextInt();
 29                     int b = input.nextInt();
 30                     int c = input.nextInt();
 31                     DateUtil date2 = new DateUtil(a,b,c);
 32                     if(b>12||b<1)
 33                         System.out.println("Wrong Format");
 34                     else {
 35                     System.out.println(date.getDaysofDates(date2));
 36                     date.getDaysofDates(date2);
 37                     break;}
 38                 }
 39                 
 40             }
 41             else
 42                 System.out.println("Wrong Format");
 43             }
 44             
 45         }
 46         else
 47             System.out.println("Wrong Format");
 48     }
 49 }
 50 
 51 
 52 
 53     class Year{
 54         private int value;
 55 
 56         public Year() {
 57             super();
 58         }
 59 
 60         public Year(int value) {
 61             super();
 62             this.value = value;
 63         }
 64 
 65         public int getValue() {
 66             return value;
 67         }
 68 
 69         public void setValue(int value) {
 70             this.value = value;
 71         }
 72         public boolean isLeapYear() {
 73             if ((this.value % 4 == 0 && this.value % 100 != 0 )|| this.value % 400 == 0)
 74                 return true;
 75             else
 76                 return false;
 77         }
 78         public boolean validate() {
 79             if(getValue() >= 1900 && getValue() <= 2050 )
 80                 return true;
 81             else
 82                 return false;
 83         }
 84         public void yearIncrement() {
 85             this.value ++;
 86         }
 87         public void yearReduction() {
 88             this.value --;
 89         }
 90     }
 91     
 92     class Month{
 93         private int value;
 94         private Year year = new Year();
 95         
 96         public Month() {
 97             super();
 98         }
 99         
100         public Month(int yearValue, int monthValue) {
101             this.year.setValue(yearValue);
102             this.value = monthValue ;
103             
104         }
105 
106         public int getValue() {
107             return value;
108         }
109 
110         public void setValue(int value) {
111             this.value = value;
112         }
113 
114         public Year getYear() {
115             return year;
116         }
117 
118         public void setYear(Year year) {
119             this.year = year;
120         }
121 
122         public void resetMin() {
123             this.value = 1;
124         }
125         
126         public void resetMax() {
127             this.value = 12;
128         }
129         
130         public boolean validate() {
131             if(year.validate() && this.value >= 1 && this.value <= 12)
132                 return true; 
133             else 
134                 return false;
135         }
136         
137         public void monthIncrement() {
138             if(this.value == 12) {
139                 year.yearIncrement();
140                 resetMin();
141             }
142             else
143             this.value ++;
144         }
145         
146         public void monthReduction() {
147             if(this.value == 1) {
148                 year.yearReduction();
149                 resetMax();
150             }
151             else
152             this.value --;
153         }
154         
155     }
156     
157     class Day{
158         private int value;
159         private Month month = new Month();
160         private int [] mon_maxnum = {31,28,31,30,31,30,31,31,30,31,30,31};
161         
162         public Day() {
163             
164         }
165         
166         public Day(int yearValue,int monthValue,int dayValue) {
167             this.month.getYear().setValue(yearValue);
168             this.month.setValue(monthValue);
169             this.value = dayValue;
170             
171         }
172 
173         public int getValue() {
174             return value;
175         }
176 
177         public void setValue(int value) {
178             this.value = value;
179         }
180 
181         public Month getMonth() {
182             return month;
183         }
184 
185         public void setMonth(Month month) {
186             this.month = month;
187         }
188         
189         public void resetMin() {
190             this.value = 1;
191         }
192         public void resetMax() {
193             this.value = getMaxOfmonth();
194         }
195         public void resetMMax() {
196             switch (month.getValue()) {
197             case 1:this.value = mon_maxnum[0];break;
198             case 2:
199                 if(month.getYear().isLeapYear()) {
200                     this.value = mon_maxnum[1] + 1;
201                     }
202                 else
203                     this.value = mon_maxnum[1];
204                     break;
205             case 3:this.value = mon_maxnum[2];break;
206             case 4:this.value = mon_maxnum[3];break;
207             case 5:this.value = mon_maxnum[4];break;
208             case 6:this.value = mon_maxnum[5];break;
209             case 7:this.value = mon_maxnum[6];break;
210             case 8:this.value = mon_maxnum[7];break;
211             case 9:this.value = mon_maxnum[8];break;
212             case 10:this.value = mon_maxnum[9];break;
213             case 11:this.value = mon_maxnum[10];break;
214             case 12:this.value = mon_maxnum[11];break;
215             default:;break;
216             }
217         }
218         public int getMaxOfmonth() {
219             if(month.getYear().isLeapYear() && month.getValue() == 2)
220                 return 29;
221             else
222                 return mon_maxnum[month.getValue()-1];
223         }
224         public int returnMonthMax() {
225             switch (month.getValue()) {
226             case 1:return mon_maxnum[0];
227             case 2:
228                 if(month.getYear().isLeapYear()) {
229                     return mon_maxnum[1];
230                     }
231                 else
232                     return mon_maxnum[1] + 1;
233             
234             case 3:return mon_maxnum[2];
235             case 4:return mon_maxnum[3];
236             case 5:return mon_maxnum[4];
237             case 6:return mon_maxnum[5];
238             case 7:return mon_maxnum[6];
239             case 8:return mon_maxnum[7];
240             case 9:return mon_maxnum[8];
241             case 10:return mon_maxnum[9];
242             case 11:return mon_maxnum[10];
243             case 12:return mon_maxnum[11];
244             default:;break;
245             }
246             return 0;
247         }
248         public boolean validate(){
249             if(month.validate()&&this.value <= getMaxOfmonth()&&this.value >= 1 )
250                 return true;
251             else
252                 return false;
253         }
254         
255         public void dayIncrement() {
256             if(this.value == getMaxOfmonth()) {
257                 month.monthIncrement();
258                 resetMin();
259             }
260             else
261             this.value ++;
262         }
263         public void dayReduction() {
264             if(this.value == 1) {
265                 month.monthReduction();
266                 resetMax();
267             }
268             else
269             this.value --;
270         }
271     }
272 
273     
274     
275     
276         class    DateUtil{
277             private Day day = new Day();
278 
279             public DateUtil() {
280                 super();
281             }
282             public DateUtil(int y,int m, int d) {
283                 day.getMonth().getYear().setValue(y);
284                 day.getMonth().setValue(m);
285                 day.setValue(d);
286             }
287             public Day getDay() {
288                 return day;
289             }
290             public void setDay(Day day) {
291                 this.day = day;
292             }
293             public boolean checkInputValidity() {
294                 if(day.getMonth().getYear().validate() &&  day.getMonth().validate() && day.validate())
295             return true;
296                 else 
297                     return false;
298             }
299             
300             public String showDate() {
301                 return this.day.getMonth().getYear().getValue()+"-"+this.day.getMonth().getValue()+"-"+this.day.getValue();
302             }
303             
304             public boolean compareDates(DateUtil date) {
305                 int a = date.day.getMonth().getYear().getValue()*20000+date.day.getMonth().getValue()*1000+date.day.getValue();
306                 int b = this.day.getMonth().getYear().getValue()*20000+this.day.getMonth().getValue()*1000+this.day.getValue();
307                 if(a<b)
308                     return false;
309                 else
310                     return true;
311             }
312             
313             public boolean equalTwoDates(DateUtil date) {
314                 if(date.showDate().equals(showDate()))
315                     return true;
316                 else 
317                     return false;
318             }
319             
320             public DateUtil getNextNdate(int n) {
321                 for(int i = 0; i < n ; i++) {
322                     day.dayIncrement();
323                 }
324                 return new DateUtil (day.getMonth().getYear().getValue(),day.getMonth().getValue(),day.getValue());
325             }
326             
327             public DateUtil getPreviousNDays(int n) {
328                 for(int i = 0; i < n; i ++) {
329                     day.dayReduction();
330                 }
331                 return new DateUtil (day.getMonth().getYear().getValue(),day.getMonth().getValue(),day.getValue());
332             }
333             
334             public int getDaysofDates(DateUtil date){
335                 int number = 0;
336                 if(compareDates(date)){            
337                     for(; !equalTwoDates(date); ) {
338                         date.day.dayReduction();
339                         number ++;
340                     }    
341                 }
342                 else if(!compareDates(date)){
343                     for(;!equalTwoDates(date);) {
344                         date.day.dayIncrement();
345                         number ++;
346                     }    
347                 }
348                 return number;
349                 
350             }
351         }

題目集05(7-5)源程式碼:

import java.util.Scanner;
public class Main {
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		int n = input.nextInt();
		if(n > 3 || n < 1)
			System.out.println("Wrong Format");
		else {
			int x = input.nextInt();
			int y = input.nextInt();
			int z = input.nextInt();
			DateUtil date = new DateUtil(x,y,z);
			if(date.checkInputValidate()) {
				switch(n) {
				case 1:
					int days1 = input.nextInt();
					date.getNextNdate(days1);
					System.out.println(x+"-"+y+"-"+z+" next "+days1+" days is:"+date.showDate());
					break;
				case 2:
					int days2 = input.nextInt();
					date.getPreviousNDays(days2);
					System.out.println(x+"-"+y+"-"+z+" previous "+days2+" days is:"+date.showDate());
					break;
				case 3:
					int a = input.nextInt();
					int b = input.nextInt();
					int c = input.nextInt();
					DateUtil date2 = new DateUtil(a,b,c);
					if(date2.checkInputValidate()) {
					System.out.println("The days between "+date.showDate()+" and "+date2.showDate()+" are:"+date.getDaysofDates(date2));
					break;
					}
				}
				
			}
			else
				System.out.println("Wrong Format");
			
		}
		
	}
}
	
	class Year{
		private int value;

		public Year() {
			super();
		}

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

		public int getValue() {
			return 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(getValue() >= 1820 && getValue() <= 2020 )
				return true;
			else
				return false;
		}
		public void yearIncrement() {
			this.value ++;
		}
		public void yearReduction() {
			this.value --;
		}
	}
	
	class Month{
		private int value;
		
		public Month() {
			super();
		}
		
		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() {
			if(this.value >= 1 && this.value <= 12)
				return true; 
			else 
				return false;
		}
		
		public void monthIncrement() {
			
			this.value ++;
		}
		
		public void monthReduction() {
			
			this.value --;
		}
		
	}
	
	class Day{
		private int value;
		public Day() {
			
		}
		public Day(int value) {
			super();
			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	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() {
				super();
				
			}
			public DateUtil(int y,int m,int d) {
				super();
				year.setValue(y);
				month.setValue(m);
				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 day) {
				this.day = day;
			}
			private void setDayMin() {
				day.setValue(1);
			}
			private void setDayMax() {
				day.setValue(getDayMax());
				
			}
			public int getDayMax() {
				if(year.isLeapYear() && month.getValue() == 2) {
					return 29;
				}
				else {
					return mon_maxnum[month.getValue()-1];
				}
			}
			public boolean checkInputValidate() {
				if(year.validate() && month.validate()) {
					if(day.getValue() >= 1 && day.getValue() <= getDayMax() )
						return true;
					else
						return false;
				}
				else
					return false;
			}
			public DateUtil getNextNdate(long n) {
				for(int i = 0; i < n ; i ++ ) {
			
					if(month.getValue() == 12 && day.getValue() == 31) {
						month.resetMin();
						setDayMin();
						year.yearIncrement();
					}
					else if(day.getValue() == getDayMax()) {
						day.setValue(1);
						month.monthIncrement();
					}
					else
						day.dayIncrement();
				}
				return new DateUtil(year.getValue(),month.getValue(),day.getValue());
			}
			public DateUtil getPreviousNDays(long n) {
				for(int i = 0; i < n ; i ++ ) {
					if(month.getValue() == 1 && day.getValue() == 1) {
						year.yearReduction();
						month.resetMax();
						setDayMax();
					}
					else if(day.getValue() == 1) {
						month.monthReduction();
						setDayMax();
						
					}
					else
						day.dayReduction();
						
				}
				return new DateUtil(year.getValue(),month.getValue(),day.getValue());
			}
			
			public int getDaysofDates(DateUtil date) {
				int num = 0;
				if(equalTwoDates( date))
				return 0;
				if(compareDates( date)) {
					for(;!equalTwoDates( date);) {
						if(month.getValue() == 12 && day.getValue() == 31) {
							month.resetMin();
							setDayMin();
							year.yearIncrement();
						}
						else if(day.getValue() == getDayMax()) {
							day.setValue(1);
							month.monthIncrement();
						}
						else
							day.dayIncrement();
						num ++;
						
						
					}
				}
				else if(!compareDates( date)) {
					for(;!equalTwoDates( date);) {
						if(month.getValue() == 1 && day.getValue() == 1) {
							year.yearReduction();
							month.resetMax();
							setDayMax();
						}
						else if(day.getValue() == 1) {
							month.monthReduction();
							setDayMax();
							
						}
						else
							day.dayReduction();
						num ++;
						
					}
				}
				return num;
			}
			
			public boolean compareDates(DateUtil date) {
				int a = date.year.getValue()*20000+date.month.getValue()*1000+date.day.getValue();
				int b = this.year.getValue()*20000+this.month.getValue()*1000+this.day.getValue();
				if(a > b)
					return true;
				else
					return false;
			}
			public boolean equalTwoDates(DateUtil date) {
				if(date.showDate().equals(showDate()))
					return true;
				else 
					return false;
			}
			
			public String showDate() {
				return year.getValue()+"-"+month.getValue()+"-"+day.getValue();
			}
	
		}

SourceMonitor的生成報表內容:

題目集04(7-2):

題目集05(7-5):

 類圖:

題目集04(7-2):

題目集05(7-5):

根據SourceMonitor的生成報表可以看到兩個程式的圈複雜程度相差不大,這兩道題相比之前的日期類題目,圈複雜度已經大大的降低了,再根據類圖來分析兩個程式的不同,首先第一個程式是遞進式的聚合,一環套一環,year類最先寫,然後在month類中創建了一個year類的對象當作month類的一個屬性,然後在day類中又創建了一個month對象作為day類中的屬性,最後在日期處理類中創建了一個day的對象當作它的屬性,整體來說就是一環扣一環,不可分割,第二個程式year,month,day等類是分開的,他們之間並沒有聯繫,由一個日期處理類將他們聯繫在一起。

優劣分析:

我認為第一個程式的聚合耦合度非常的高,因為環環相扣,他的劣勢在於,如果其中某個環節除了錯誤,很難改正,尤其是到後面才發現錯誤,就可能要把整個程式都改一下,類與類之間的關係太緊密了,每當要用到year的方法,需要從DateUtil調用day再調用month再調用year,調用起來也比較複雜,但是它也有他的優點,到最後實現前n天或者後n天的時候,它只需要調用一個day的加減就可以了,因為之前做了鋪墊,程式的邏輯就比較簡單了。

我認為第二個程式總體來說應該是優於第一個程式的,首先它的年月日的類是分開的,它們之間是沒有直接的關係的,耦合程度非常的低,就算我其中一個類出錯了,和其他的類也沒有什麼關係,而且出錯之後非常的好修改,也知道錯在哪裡,而他得缺點就是到最後的日期處理類中,我們需要進行一些思考,去完成前n天后n天的實現,我們知道,java類與類之間的耦合程度越低越好,且第二個程式很好的保證了類的單一職責的原則,所以我認為第二個程式總體來說比第一個好一些。

(2)題目集04(7-3)題目集06(7-5、7-6)

題目集04(7-3):

編寫程式,實現圖形類的繼承,並定義相應類對象並進行測試。

  1. 類Shape,無屬性,有一個返回0.0的求圖形面積的公有方法public double getArea();//求圖形面積
  2. 類Circle,繼承自Shape,有一個私有實型的屬性radius(半徑),重寫父類繼承來的求面積方法,求圓的面積
  3. 類Rectangle,繼承自Shape,有兩個私有實型屬性width和length,重寫父類繼承來的求面積方法,求矩形的面積
  4. 類Ball,繼承自Circle,其屬性從父類繼承,重寫父類求面積方法,求球表面積,此外,定義一求球體積的方法public double getVolume();//求球體積
  5. 類Box,繼承自Rectangle,除從父類繼承的屬性外,再定義一個屬性height,重寫父類繼承來的求面積方法,求立方體表面積,此外,定義一求立方體體積的方法public double getVolume();//求立方體體積
  6. 注意:
  • 每個類均有構造方法,且構造方法內必須輸出如下內容:Constructing 類名
  • 每個類屬性均為私有,且必須有getter和setter方法(可用Eclipse自動生成)
  • 輸出的數值均保留兩位小數

主方法內,主要實現四個功能(1-4): 從鍵盤輸入1,則定義圓類,從鍵盤輸入圓的半徑後,主要輸出圓的面積; 從鍵盤輸入2,則定義矩形類,從鍵盤輸入矩形的寬和長後,主要輸出矩形的面積; 從鍵盤輸入3,則定義球類,從鍵盤輸進球的半徑後,主要輸出球的表面積和體積; 從鍵盤輸入4,則定義立方體類,從鍵盤輸入立方體的寬、長和高度後,主要輸出立方體的表面積和體積;

假如數據輸入非法(包括圓、矩形、球及立方體對象的屬性不大於0和輸入選擇值非1-4),系統輸出Wrong Format

輸入格式:

共四種合法輸入

  • 1 圓半徑
  • 2 矩形寬、長
  • 3 球半徑
  • 4 立方體寬、長、高

輸出格式:

按照以上需求提示依次輸出

源碼如下:

  1 import java.util.Scanner;
  2 
  3 public class Main {
  4 
  5     public static void main(String[] args) {
  6         Scanner input = new Scanner(System.in);
  7         int n = input.nextInt();
  8         if(n > 4 || n < 1) {
  9             System.out.println("Wrong Format");
 10             System.exit(0);
 11         }
 12     
 13             switch(n){
 14             case 1:
 15             
 16             double r = input.nextDouble();
 17             if(r < 0) {
 18                 System.out.println("Wrong Format");
 19             System.exit(0);}
 20             else {
 21                 Circle c = new Circle();
 22                 c.setRadius(r);
 23                 System.out.println("Circle's area:"+String.format("%.2f", c.getArea()));
 24             }
 25             break;
 26             case 2:
 27                 
 28                 double chang = input.nextDouble();
 29                 double kuan = input.nextDouble();
 30                 if(chang < 0 ||kuan < 0) {
 31                     System.out.println("Wrong Format");
 32                     System.exit(0);
 33                     }
 34                 else {
 35                     Rectangle zf = new Rectangle();
 36                     zf.setLength(chang);
 37                     zf.setWidth(kuan);
 38                     System.out.println("Rectangle's area:"+String.format("%.2f", zf.getArea()));
 39                 }break;
 40             case 3:
 41             
 42                 double R = input.nextDouble();
 43                 if(R < 0) {
 44                     System.out.println("Wrong Format");
 45                     System.exit(0);
 46                 }
 47                 else {
 48                     Ball b = new Ball();
 49                     b.setRadius(R);
 50                     System.out.println("Ball's surface area:"+String.format("%.2f", b.getArea()));
 51                     System.out.println("Ball's volume:"+String.format("%.2f",b.getVolume() ));
 52                 }
 53                 break;
 54             case 4:
 55                 
 56                 double ch = input.nextDouble();
 57                 double ku = input.nextDouble();
 58                 double gao = input.nextDouble();
 59                 if(ch < 0 || ku < 0 || gao < 0) {
 60                     System.out.println("Wrong Format");
 61                     System.exit(0);
 62                 }
 63                 else {
 64                     Box B = new Box();
 65                     B.setLength(ch);
 66                     B.setWidth(ku);
 67                     B.setHeight(gao);
 68                     System.out.println("Box's surface area:"+String.format("%.2f",B.getArea() ));
 69                     System.out.println(String.format("Box's volume:"+"%.2f",B.getVolume() ));
 70                 }
 71                 break;
 72             default:;
 73             }
 74         }
 75 
 76 
 77     private static void Switch(int n) {
 78         // TODO 自動生成的方法存根
 79         
 80     }
 81     }
 82 class Shape{
 83     public Shape() {
 84         super();
 85         System.out.println("Constructing Shape");
 86     }
 87     public double getArea() {
 88         return 0.0;
 89     }
 90 }
 91 class Circle extends Shape{
 92     private double radius;
 93     
 94     public double getArea() {
 95         return Math.PI*Math.pow(this.getRadius(), 2);
 96     }
 97     public Circle() {
 98         super();
 99         System.out.println("Constructing Circle");
100     }
101     public double getRadius() {
102         return radius;
103     }
104     public void setRadius(double radius) {
105         this.radius = radius;
106     }
107     
108 } 
109 class Rectangle extends Shape{
110     private double width ;
111     private double length;
112     
113     public double getWidth() {
114         return width;
115     }
116 
117     public void setWidth(double width) {
118         this.width = width;
119     }
120 
121     public double getLength() {
122         return length;
123     }
124 
125     public void setLength(double length) {
126         this.length = length;
127     }
128 
129     public double getArea() {
130         return this.length*this.width;
131     }
132 
133     public Rectangle() {
134         super();
135         System.out.println("Constructing Rectangle");
136     }
137 }
138 class Ball extends Circle{
139 
140     public Ball() {
141         super();
142         System.out.println("Constructing Ball");
143         
144     }
145     public double getArea() {
146         return 4*Math.PI*getRadius()*getRadius();
147     }
148     
149     public double getVolume() {
150         return 4.0/3*Math.PI*getRadius()*getRadius()*getRadius();
151     }
152 }
153 class Box extends Rectangle{
154     private double height;
155     
156     public double getHeight() {
157         return height;
158     }
159     public void setHeight(double height) {
160         this.height = height;
161     }
162     public double getArea() {
163         return 2*(getWidth()*getLength()+getWidth()*this.height+getLength()*this.height);
164     }
165     public double getVolume() {
166         return this.height*getLength()*getWidth();
167     }
168 
169     public Box() {
170         super();
171         System.out.println("Constructing Box");
172     }
173     
174 }

SourceMonitor的生成報表內容:

類圖如下:

題目集06(7-5):

掌握類的繼承、多態性及其使用方法。

輸入格式:

從鍵盤首先輸入三個整型值(例如a b c),分別代表想要創建的Circle、Rectangle及Triangle對象的數量,然後根據圖形數量繼續輸入各對象的屬性值(均為實型數),數與數之間可以用一個或多個空格或回車分隔。

輸出格式:

  1. 如果圖形數量非法(小於0)或圖形屬性值非法(數值小於0以及三角形三邊關係),則輸出Wrong Format

  2. 如果輸入合法,則正常輸出,輸出內容如下(輸出格式見輸入輸出示例):

  • 各個圖形的面積;

  • 所有圖形的面積總和;

  • 排序後的各個圖形面積;

  • 再次所有圖形的面積總和。

源碼如下:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
public class Main{
    public static void main(String[] args) {
    	Scanner input = new Scanner(System.in);
    			int a = input.nextInt();
    			int b = input.nextInt();
    			int c = input.nextInt();
    			if(a < 0 || b < 0 || c < 0)
    				
        				System.out.println("Wrong Format");
    			else {
    				Circle  [] cir  = new Circle[a];
    				Rectangle [] rec = new Rectangle[b];
    				Triangle [] tri = new Triangle[c];
    				ArrayList <Shape> list = new ArrayList<Shape>();
    				for(int i = 0; i < a; i ++) {
    					 cir [i] = new Circle(input.nextDouble());
    					 if(cir[i].validate() == false) {
    						 System.out.println("Wrong Format"); 
    						 System.exit(0);
    					 }
    					 list.add(cir[i]);
    				}
    				for(int i = 0; i < b ; i ++) {
    					rec[i] = new Rectangle(input.nextDouble(),input.nextDouble());
    					if(rec[i].validate() == false) {
    						System.out.println("Wrong Format"); 
   						    System.exit(0);
    					}
    					list.add(rec[i]);
    					
    				}
    				for(int i = 0;  i < c; i ++) {
    					tri[i] = new Triangle(input.nextDouble(),input.nextDouble(),input.nextDouble());
    					if(tri[i].validate() == false) {
    						System.out.println("Wrong Format"); 
   						    System.exit(0);	
    					}
    					list.add(tri[i]);
    				}
    				
    				double sum = 0;
    				System.out.println("Original area:");
    				for(int i =0; i < a+b+c; i ++) {
    				System.out.printf(String.format("%.2f", list.get(i).getArea()).toString()+" ");
    				 sum = sum + list.get(i).getArea();
    				}
 
    			    System.out.println("\n"+"Sum of area:"+String.format("%.2f", sum).toString());
    			    for(int i = 0; i < a+b+c - 1; i++)
    			    	for(int j = 0; j < a + b + c - 1 - i;j ++) {
    			    		if(list.get(j).getArea() > list.get(j+1).getArea())
    			    			Collections.swap(list, j, j+1);
    			    	}
    			    System.out.println("Sorted area:");
    			    for(int i =0; i < a+b+c; i ++) {
        				System.out.print(String.format("%.2f", list.get(i).getArea()).toString()+" ");
        				
        				}
    			    System.out.print("\n"+"Sum of area:"+String.format("%.2f", sum).toString());
    			}
    			
    			
//System.out.println(String.format("%.2f", r.getArea()).toString());
    }
}

abstract class Shape {
	public abstract double getArea();
	public abstract boolean validate();
	//@Override
	/*public String toString() {
		return "Shape [getClass()=" + getClass() + ", hashCode()=" + hashCode() + ", toString()=" + super.toString()
				+ "]";
	}	*/
}


class Circle extends Shape{
	private double radius;

	public Circle() {
		super();
	}

	public Circle(double radius) {
		super();
		this.radius = radius;
	}
	public double getArea() {
		return Math.PI*this.radius * this.radius ;
	}
	public boolean validate() {
		if(this.radius <= 0)
			return false;
		else 
			return true;
	}
	
}


class Rectangle extends Shape{
	private double width;
	private double length;
	public Rectangle() {
		super();
		// TODO 自動生成的構造函數存根
	}
	public Rectangle(double width, double length) {
		super();
		this.width = width;
		this.length = length;
	}
	public double getArea() {
		return this.length *this.width;
	}
	public boolean validate() {
		if(this.length > 0 && this.width > 0)
			return true;
		else
			return false;
	}
}


class Triangle extends Shape{
	private double side1;
	private double side2;
	private double side3;
	public Triangle() {
		super();
		// TODO 自動生成的構造函數存根
	}
	public Triangle(double side1, double side2, double side3) {
		super();
		this.side1 = side1;
		this.side2 = side2;
		this.side3 = side3;
	}
	
	public double getArea() {
		double s = (this.side1 + this.side2 + this.side3)/2.0;
		return Math.sqrt(s * (s - this.side1) * (s - this.side2) * (s - this.side3));
	}
	public boolean validate() {
		if(this.side1 > 0 && this.side2 > 0 && this.side3 > 0) {
			if(this.side1 + this.side2 > this.side3 && this.side1 + this.side3 > this.side2 && this.side2 + this.side3 > this.side1)
				return true;
			else 
				return false;
		
		}
		else 
			return false;
	}
}

SourceMonitor的生成報表內容:

 類圖如下:

題目集06(7-6):

編寫程式,使用介面及類實現多態性。

其中:

  • GetArea為一個介面,無屬性,只有一個GetArea(求面積)的抽象方法;
  • Circle及Rectangle分別為圓類及矩形類,分別實現GetArea介面
  • 要求:在Main類的主方法中分別定義一個圓類對象及矩形類對象(其屬性值由鍵盤輸入),使用介面的引用分別調用圓類對象及矩形類對象的求面積的方法,直接輸出兩個圖形的面積值。(要求只保留兩位小數)

輸入格式:

從鍵盤分別輸入圓的半徑值及矩形的寬、長的值,用空格分開。

輸出格式:

  • 如果輸入的圓的半徑值及矩形的寬、長的值非法(≤0),則輸出Wrong Format
  • 如果輸入合法,則分別輸出圓的面積和矩形的面積值(各佔一行),保留兩位小數。

 源碼如下:

import java.util.Scanner;
public class Main{
    public static void main(String[] args) {
    	Scanner input = new Scanner(System.in);
    			double x = input.nextDouble();
    			Circle c = new Circle(x);
    			double y = input.nextDouble();
    			double z = input.nextDouble();
    			Rectangle r = new Rectangle(y,z);
    			if(x <= 0 || y <= 0 || z  <= 0) {
    				System.out.println("Wrong Format");
    				System.exit(0);
    			}
    			
    			System.out.println(String.format("%.2f", c.getArea()).toString());
    			System.out.println(String.format("%.2f", r.getArea()).toString());
    }
}

class Circle implements GetArea{
	private double radius;

	public Circle() {
		super();
		
	}

	public Circle(double radius) {
		super();
		this.radius = radius;
	}

	public double getRadius() {
		return radius;
	}

	public void setRadius(double radius) {
		this.radius = radius;
	}
	public double getArea() {
		return Math.PI*this.radius*this.radius;
	}
	
}
class Rectangle implements GetArea{
	private double width;
	private double length;
	public Rectangle() {
		super();
		
	}
	public Rectangle(double width, double length) {
		super();
		this.width = width;
		this.length = length;
	}
	public double getWidth() {
		return width;
	}
	public void setWidth(double width) {
		this.width = width;
	}
	public double getLength() {
		return length;
	}
	public void setLength(double length) {
		this.length = length;
	}
	public double getArea() {
		return this.length*this.width;
	}
}
 interface GetArea{
	public double getArea();
}
    
    

SourceMonitor的生成報表內容:

類圖如下:

 這三道題都是繼承類題目,第一題要求我們求面積等,首先第一題有一個總的Shape類,一個圖形類,圖形可以包括很多種,它的子類包含了一個Circle類和Rectangle類,這裡的類都不是抽象類,是普通類,Shape類有一個getArea的方法,然後在Circle和Rectangle類中重寫了求面積的方法,在這個基礎上,又寫了兩個類Ball和Box分別繼承了Circle類和Rectangle類,Ball類和Box類中又重寫了求面積的方法,又增加了求體積的方法,每個類中都會輸出自己的類名,就是一旦跟這個類有關就會輸出這個類的類名,我覺得這道題更多是想幫助我們去理解繼承這個東西,理解繼承的好處,子類可以調用父類的方法,所以從而可以簡單的實現共有的一些功能,可以減少程式碼量,如果子類的計算方法和父類不一樣,還可以重寫其方法來達到目的,繼承是Java中很重要的一個內容,我們想實現一些東西,在不改變自身程式碼的情況下,我們可以給之前的程式碼加一個父類,就像老師實驗課所講的例子,如果我想給空調加一個做飯的功能而且不能對源碼做出改變,應該怎麼做,我想這時候就可以給它加一個父類來實現一些功能。

第二題也是要求我們求圖形的面積,根據圖形面積對圖形對象進行排序並輸出,第二題,這道題採用了抽象類定義,實體類構建的一個方式,我們首先有一個Shape類,但這個類與上一題不同的是,這是一個抽象類,擁有抽象的方法,求面積和數據校驗,然後它有三個子類分別是,circle類rectangle類和triangle類分別,三個類繼承於shape類,重寫了求面積和數據校驗的方法,我在主函數中分別創建三個類的對象然後將他們放入shape類型的list中,求面積的時候直接調用shape的getArea的方法就可以了,然後再根據面積對list中的對象排序,最後再輸出面積。我認為這道題主要是想讓我們更深刻的理解繼承以及去理解多態,我們求面積只需要調用shape的求面積方法,就可以直接求面積,不需要調用誰誰的求面積去求誰誰的面積,就像老師上課舉得交學費的例子,學校說交學費,只需要說一句交學費,人人就都知道自己交多少學費,學校不用去和每個學院的人說你們交多少多少學費,這就是多態的好處,繼承和多態提高了程式碼的可維護性和可延展性。

第三題還是讓我們求面積,不過第三題與第一題和第二題都不同的是第三題讓我們使用介面來實現多態,首先我們創建了一個求面積的介面,介面中有一個求面積的的方法,然後創建了倆個類一個是circle類一個是rectangle類,這兩個類都與介面相連接,這兩個類中都有求面積的方法,然後我們在主函數中創建兩個對象,聲明類型為介面,實際類型還是circle和rectangle,然後調用介面求面積的方法就可以求出面積。這道題主要的目的應該是想讓了解介面,然後用介面以及類實現多態。

三道題核心的內容其實基本都相似,都是想讓我們理解多態,通過繼承通過介面來理解多態,多態就是同一操作作用於不同的對象,可以有不同的解釋,產生不同的執行結果,我們知道,封裝可以隱藏實現細節,使得程式碼模組化,繼承可以擴展已存在的程式碼模組,他們都是為了程式碼的復用,而多態除了程式碼的復用性外,還可以解決項目中緊偶合的問題,提高程式的可擴展性.。

 (3)對三次題目集中用到的正則表達式技術的分析總結

三次題目集中,題目集04(7-1)題目集05(7-4),題目集06(1、2、4)都是正則表達式的練習。

正則表達式常用的知識點總結:

.     匹配除換行符以外的任意字元

\w  匹配字母或數字或下劃線

\s  匹配任意的空白符

\d  匹配數字

\b  匹配單詞的開始或結束

^  匹配字元串的開始

$  匹配字元串的結束

*  重複零次或更多次

+  重複一次或更多次

?  重複零次或一次

n  重複n次

{n,}  重複n次或更多次

{n,m}  重複n到m次

\W  匹配任意不是字母,數字,下劃線,漢字的字元

\S  匹配任意不是空白符的字元

\D  匹配任意非數字的字元

\B  匹配不是單詞開頭或結束的位置

[^x]  匹配除了x以外的任意字元

 [^asdf]  匹配除了asdf這幾個字母以外的任意字元

  • Pattern 類:

    pattern 對象是一個正則表達式的編譯表示。Pattern 類沒有公共構造方法。要創建一個 Pattern 對象,你必須首先調用其公共靜態編譯方法,它返回一個 Pattern 對象。該方法接受一個正則表達式作為它的第一個參數。

  • Matcher 類:

    Matcher 對象是對輸入字元串進行解釋和匹配操作的引擎。與Pattern 類一樣,Matcher 也沒有公共構造方法。你需要調用 Pattern 對象的 matcher 方法來獲得一個 Matcher 對象。

public boolean lookingAt()
 嘗試將從區域開頭開始的輸入序列與該模式匹配。

public boolean find()
嘗試查找與該模式匹配的輸入序列的下一個子序列。

public boolean find(int start)
重置此匹配器,然後嘗試查找匹配該模式、從指定索引開始的輸入序列的下一個子序列。

 public boolean matches()
嘗試將整個區域與模式匹配。

public String replaceAll(String replacement)
 替換模式與給定替換字元串相匹配的輸入序列的每個子序列。

public String replaceFirst(String replacement)
 替換模式與給定替換字元串匹配的輸入序列的第一個子序列。

以上是一些最常用的正則表達式的知識點。題目集04(7-1)是水文數據校驗及處理,該題讓我們使用Java中的字元串處理類以及正則表達式對輸入字元串數據進行合法性校驗及計算,主要考察的就是我們利用正則表達式去匹配和操作,然後還考察了我們對字元串的處理,題目集05(7-4)統計Java程式中關鍵詞的出現次數,該題考察點和上題考查的內容相似,但是第五題考察的非法情況以及注意事項更多一些,所以我認為難度還略大於上一題,前兩道題目比較綜合,後面的三道小題就比較簡單了,考察的都是一些基礎知識點。

總的來說,正則表達式可以使我們的程式碼簡單,我們用起來非常的方便,如果沒有正則表達式,我們可能要用for循環一個一個去判斷,所以正則表達式是幫助我們去操作字元串的一個好的工具。

(4)題目集05(7-4)中Java集合框架應用的分析總結

題目集05(7-4)統計Java程式中關鍵詞的出現次數

編寫程式統計一個輸入的Java源碼中關鍵字(區分大小寫)出現的次數。說明如下:

  • Java中共有53個關鍵字(自行百度)
  • 從鍵盤輸入一段源碼,統計這段源碼中出現的關鍵字的數量
  • 注釋中出現的關鍵字不用統計
  • 字元串中出現的關鍵字不用統計
  • 統計出的關鍵字及數量按照關鍵字升序進行排序輸出
  • 未輸入源碼則認為輸入非法

輸入格式:

輸入Java源碼字元串,可以一行或多行,以exit行作為結束標誌

輸出格式:

  • 當未輸入源碼時,程式輸出Wrong Format
  • 當沒有統計數據時,輸出為空
  • 當有統計數據時,關鍵字按照升序排列,每行輸出一個關鍵字及數量,格式為數量\t關鍵字

這道題讓我們匹配關鍵字,用到了正則表達式以及對字元串的操作和處理,題目還要求題目必須使用List、Set或Map中一種或多種,如完全未使用如上介面,是一道綜合性題目,由於本題難度較大,改題目並沒有完全完成。所以對該道題目的分析可能不多。

對於這道題目,剛開始看到這道題的時候感覺難度還行,有一些大致的思路,先輸入字元串,然後用正則表達式匹配,統計然後輸出,但下手的時候發現不太能下手,由於題目有很多細節的需求,以及我自己正則表達式和對字元串的應用不是很熟,所以這道題目並沒有完全做完。

3.踩坑心得

(1)第一道日期題目對於月份最大值的處理一開始用了switch和case,列舉了12個月,到最後發現了mon_maxnum這個數組都沒有用上,用case的時候不僅容易錯,而且非常複雜,在第二個程式碼中就把返回月份最大值,直接用一個簡單的方法返回了,下次做題的時候應該考慮清楚類圖中的一些屬性都有什麼用,該怎麼使用,然後再進行寫程式碼的工作,這樣可能會節省很多時間。

(2)第一道日期類的題目,在類與類之間傳輸數據的時候,數據對應錯了,在Day這個類中,我們創建了year和month的對象作為day這個類的屬性,然後寫了一個函數public Day(int yearValue,int monthValue,int dayValue),將數據傳到一起,但是寫完之後發現檢驗輸入數據是否合法的時候一直輸出wrong format,後來才發現對應的日期傳錯了,把年傳到了日,所以導致一開始總是找不到錯誤在哪裡,耽誤了很長的時間,其實跟那個類圖也有關係,跟自己也有關係,類圖那個年月日順序就錯了,也還是自己沒有特別仔細地閱讀題目。

(3)日期類的第二題和第一題有很多不同,因為年月日的類很簡單,所以在日期處理的類中,包括了一些核心演算法,而這個核心演算法的一些順序很重要,還是邏輯的問題,month.monthReduction();setDayMax();就比如這兩個程式碼的先後順序就很重要,如果按照自己的邏輯,它們兩個誰先誰後都無所謂,但是如果把這兩個程式碼位置換了的話,就會導致閏年2月到三月或者二月到1月出現問題,日期就會提前引用二月的日期,比如一月31日,但是運行後成了1月29日,就有一些邏輯錯誤,這個也改了一些時間。

(4)題目集06(7-5),圖形繼承的題,檢測輸入數據合法性,一開始不管輸入什麼數據,輸出都是wrong format,但是自己去看自己的程式碼覺得沒有問題,然後到最後最後還是發現了一些邏輯錯誤,就是檢驗輸入數據合法性,雖然都是判斷,但是先正常進行,再輸出wrong format 和先輸wrong format 也是不一樣的,所以要多注意這方面的邏輯,看看什麼樣的程式碼適合那種邏輯。

4.改進建議

(1)對於第一個日期題,我認為應該多保證類的單一性原則,所以就不應該每個類都聚合,應該把day,month,year類單獨設計出來,之間沒有關聯,就向著第二道日期題改進即可。

(2)對於題目集04第三題,繼承類題目,我認為可以寫一個操作類,然後把求面積的方法都放在這一個類中,然後讓這個類繼承這個操作類,以後還可以加求體積等方法,很方便。

5.總結

(1)首先呢,學到了一些正則表達式的知識點以及應用 還需要多加練習,更熟悉的掌握正則表達式的知識點以及用法。

(2)其次,學習到了類與類之間的關係,我認為這次最重要的就是明白了很多類與類之間的關係,比如關聯,聚合,繼承。

(3)我覺得這次的題目集,我對於繼承有了更深的理解,因為理解了繼承的好處,明白了它有什麼用處,所以更好了理解了為什麼要用繼承,繼承怎樣使用。

(4)對於類的設計,整個程式碼的設計,以及類與類之間的關係還需要進一步學習,需要通過練習來進一步掌握知識。

(5)對於老師講課的話沒有很多意見,就是希望老師可以多帶著我們寫一些程式碼,感覺這樣效果會好一些。