20145308劉昊陽 《Java程式設計》實驗二 Java面向物件程式設計 實驗報告

實驗名稱

  • Java面向物件程式設計

實驗內容

  • 初步掌握單元測試和TDD
  • 理解並掌握面相物件三要素:封裝、繼承、多型
  • 初步掌握UML建模
  • 掌握S.O.L.I.D原則
  • 瞭解設計模式

統計的PSP(Personal Software Process)時間

步驟 耗時(min) 百分比
需求分析 20~30 12.5%
設計 20~30 12.5%
程式碼實現 50~60 25%
測試 50~60 25%
分析總結 50~60 25%

實驗步驟

(一)單元測試

  • 用實驗示例程式碼進行試驗

    • 寫完了第一代程式碼,建立MyUtilTest類,並書寫Test程式碼,通過編譯

  • 輸入負分檢測,出現bug

  • 修改程式,使之能夠處理負分情況

  • 測試邊界情況,出現bug

  • 修改程式,使之能處理邊界情況

  • 使用TDD的方式設計實現複數類Complex

    • 首先建立test類,建立java檔案,並將java檔案go to到建立的test
    • 根據所想功能書寫test
import org.junit.Test;
public class ComplexNumberTest {
@Test
public void ComplexNumber(){
//ComplexNumber()方法
ComplexNumber num1 = new ComplexNumber();
assert num1.m_dRealPart == 0 : "fault1:ComplexNumber()函式有錯誤";
assert num1.m_dImaginPart == 0 : "fault2:ComplexNumber()函式有錯誤"; //ComplexNumber(double r,double I)方法
ComplexNumber num2 = new ComplexNumber(0, 0);
assert num2.m_dRealPart == 0 : "fault3:ComplexNumber(double r,double I)函式有錯誤";
assert num2.m_dImaginPart == 0 : "fault4:ComplexNumber(double r,double I)函式有錯誤"; //GetRealPart()方法
assert num2.m_dRealPart == 0 : "fault5:GetRealPart()函式有錯誤"; //GetImaginaryPart()方法
assert num2.m_dImaginPart == 0 : "fault6:GetImaginaryPart()函式有錯誤"; //SetRealPart(double d)方法
ComplexNumber num3 = new ComplexNumber();
num3.SetRealPart(0);
assert num3.m_dRealPart == 0 : "fault7:SetRealPart(double d)函式有錯誤"; //SetImaginaryPart(double d)方法
num3.SetImaginaryPart(0);
assert num3.m_dRealPart == 0 : "fault8:SetImaginaryPart(double d)函式有錯誤"; //ComplexAdd(ComplexNumber c)方法
ComplexNumber num4 = new ComplexNumber();
ComplexNumber num5 = new ComplexNumber(-1, -1);
ComplexNumber num6 = new ComplexNumber();
num4 = num1.ComplexAdd(num1);//自身相加,結果為0
assert num4.m_dRealPart == 0 : "fault9:ComplexAdd(ComplexNumber c)函式有錯誤";
assert num4.m_dImaginPart == 0 : "fault10:ComplexAdd(ComplexNumber c)函式有錯誤";
num6 = num1.ComplexAdd(num5);//結果為負數
assert num6.m_dRealPart == -1 : "fault11:ComplexAdd(ComplexNumber c)函式有錯誤";
assert num6.m_dImaginPart == -1 : "fault12:ComplexAdd(ComplexNumber c)函式有錯誤"; //ComplexMinus(ComplexNumber c)方法
ComplexNumber num7 = new ComplexNumber();
ComplexNumber num8 = new ComplexNumber(1, 1);
ComplexNumber num9 = new ComplexNumber();
num7 = num1.ComplexMinus(num1);//自身相減,結果為0
assert num7.m_dRealPart == 0 : "fault13:ComplexMinus(ComplexNumber c)函式有錯誤";
assert num7.m_dImaginPart == 0 : "fault14:ComplexMinus(ComplexNumber c)函式有錯誤";
num9 = num1.ComplexMinus(num8);//結果為負數
assert num9.m_dRealPart == -1 : "fault13:ComplexMinus(ComplexNumber c)函式有錯誤";
assert num9.m_dImaginPart == -1 : "fault14:ComplexMinus(ComplexNumber c)函式有錯誤"; //ComplexMulti(ComplexNumber c)方法
ComplexNumber num10 = new ComplexNumber();
ComplexNumber num11 = new ComplexNumber(-1, -1);
ComplexNumber num12 = new ComplexNumber();
ComplexNumber num13 = new ComplexNumber();
ComplexNumber num14 = new ComplexNumber(1, 1);
num10 = num1.ComplexMulti(num1);//自身相乘,結果為0
assert num10.m_dRealPart == 0 : "fault15:ComplexMulti(ComplexNumber c)函式有錯誤";
assert num10.m_dImaginPart == 0 : "fault16:ComplexMulti(ComplexNumber c)函式有錯誤";
num12 = num1.ComplexMulti(num11);//0與複數相乘,結果為0
assert num12.m_dRealPart == 0 : "fault17:ComplexMulti(ComplexNumber c)函式有錯誤";
assert num12.m_dImaginPart == 0 : "fault18:ComplexMulti(ComplexNumber c)函式有錯誤";
num13 = num11.ComplexMulti(num14);//正數與複數相乘,結果為負數
assert num13.m_dRealPart == -1 : "fault19:ComplexMulti(ComplexNumber c)函式有錯誤";
assert num13.m_dImaginPart == -1 : "fault20:ComplexMulti(ComplexNumber c)函式有錯誤"; //toString(double a,double b)方法
ComplexNumber num15 = new ComplexNumber(-1, -1);
ComplexNumber num16 = new ComplexNumber(0, 0);
assert num15.toString(num15.m_dRealPart, num15.m_dImaginPart).equals( -1-1+"i") : "fault21:toString(double a,double b)函式有錯誤";//實部虛部全部為複數
assert num16.toString(num16.m_dRealPart, num16.m_dImaginPart).equals(0) : "fault22e:toString(double a,double b)函式有錯誤";//實部虛部全部為0 //成功
// System.out.println("沒有發現程式錯誤");
}
}
  • 根據test檔案寫java檔案,開始進行測試,發生錯誤

  • 發現是test檔案把ComplexMulti()錯寫成ComplexAdd(),修改程式碼

  • 執行成功,出現fault21

  • 修改fault21

  • 沒有解決錯誤

  • Complex類程式碼

import java.util.Scanner;
import java.lang.String; public class ComplexNumber {
public double m_dRealPart;//實部
public double m_dImaginPart;//虛部 public ComplexNumber(){//建構函式,將實部虛部置0
double m_dRealPart = 0;
double m_dImaginPart = 0;
}
public ComplexNumber(double r,double I){//建構函式,建立複數物件的同時完成負數的實部虛部的初始化
this.m_dRealPart = r;
this.m_dImaginPart = I;
}
public double GetRealPart(){//獲取實部
return this.m_dRealPart;
}
public double GetImaginaryPart(){//獲取虛部
return this.m_dImaginPart;
}
public double SetRealPart(double d){//設定實部
m_dRealPart = d;
return m_dRealPart;
}
public double SetImaginaryPart(double d){//設定虛部
m_dImaginPart = d;
return m_dImaginPart;
}
ComplexNumber ComplexAdd(ComplexNumber c){//複數相加
double real = c.GetRealPart();
double image = c.GetImaginaryPart();
double newReal = real + m_dRealPart;
double newImage = image + m_dImaginPart;
ComplexNumber Result = new ComplexNumber(newReal,newImage);
return Result;
}
/*ComplexNumber ComplexAdd(double c){//複數相加
double real = c;
double newReal = real + m_dRealPart;
ComplexNumber Result = new ComplexNumber(newReal,0);
return Result;
}*/
ComplexNumber ComplexMinus(ComplexNumber c){//複數相減
double real = c.GetRealPart();
double image = c.GetImaginaryPart();
double newReal = m_dRealPart - real ;
double newImage = m_dImaginPart - image;
ComplexNumber Result = new ComplexNumber(newReal,newImage);
return Result;
}
/* ComplexNumber ComplexMinus(double c){//複數相減
double real = c;
double newReal = real - m_dRealPart;
ComplexNumber Result = new ComplexNumber(newReal,0);
return Result;
}*/
ComplexNumber ComplexMulti(ComplexNumber c){//複數相乘
double real = c.GetRealPart();
double image = c.GetImaginaryPart();
double newReal = real * m_dRealPart;
double newImage = image * m_dImaginPart;
ComplexNumber Result = new ComplexNumber(newReal,newImage);
return Result;
}
/*ComplexNumber ComplexMulti(double c){//複數相乘
double real = c;
double newReal = real * m_dRealPart;
ComplexNumber Result = new ComplexNumber(newReal,0);
return Result;
}*/
public String toString(double a,double b){//把當前複數物件的實部虛部組合成a+bi的字串形式
String c;
if(b == 0) {c =""+a;}//將double型變數轉為String型別
else if(b < 0){c = a+b+"i";}
else {c = a+"+"+b +"i";}
return c;
} }
  • 使用StarUML建模

    • 我的程式沒有繼承和操作介面,所以用實驗示例來做

    • 建立兩個類,設定許可權和類裡面的方法

    • 建立測試類AnimalTest,將測試類依賴這兩個類

    • 建立Animal,並設定為父類,將兩個子類設定繼承該父類,有繼承和操作介面的完整圖

問題及解決過程

  • 問題:toString類的test出錯,經過查詢程式碼,應該沒有錯誤,感覺是test檔案不對

  • 解決過程:修改程式碼還是執行不出來,有待解決

  • 問題:建模時建立了父類Animal子類無法繼承

  • 解決過程:對照示例發現Animal沒有變成斜體字,無法繼承,就勾選了Properties工具欄中的IsAbstract選項,成功

實驗體會

  • 這次實驗內容很多,學習了單元測試,還接觸了一個全新的軟體StarUML,並用軟體進行建模,感覺實驗時間雖然緊張,但是還是學習到了很多,當然也有很多沒解決的問題
  • 單元測試真的很方便,在寫程式前就可以設計好程式再進行書寫,避免有bug,還可以對書寫好的類進行全面的測試,體會到了三種程式碼的區別與用處
  • 建模將Java中類的抽象的封裝繼承關係具體到圖形上,讓人更直觀的感受到了他們之間的關係