實驗二 Java物件導向程式設計

來源:互聯網
上載者:User

標籤:單元測試工具   capacity   系統   frame   xtend   操作方法   介面   isp   抽象   

實驗二 Java物件導向程式設計實驗報告封面:
課程:Java程式設計  班級:1652班  姓名:王高源 學號:20165225指導教師:婁嘉鵬 實驗日期:2018年4月16日實驗時間:3:35 - 5:15 實驗序號:實驗二實驗名稱:Java物件導向程式設計實驗題目:實驗內容:1.初步掌握單元測試和TDD2.理解並掌握物件導向三要素:封裝、繼承、多態3.初步掌握UML建模4.熟悉S.O.L.I.D原則5.瞭解設計模式實驗要求:1.實現百分製成績轉成“優、良、中、及格、不及格”五級製成績的功能
實驗內容及步驟:註:以下許多代碼都是老師給好的,僅稍作修改。單元測試
  • TDD步驟:虛擬碼(思路)→ 測試代碼(產品預期功能)→ 產品代碼(實現預期功能),這種開發方法叫“測試驅動開發”

  • 虛擬碼:虛擬碼與具體程式設計語言無關,不要寫與具體程式設計語言文法相關的語句(如用malloc分配記憶體,這樣只能用C語言編程了),虛擬碼從意圖層面來解決問題,最終,虛擬碼是產品代碼最自然的、最好的注釋。

  • 故根據實驗題目要求,我們應先寫出相應的“虛擬碼”以便於我們完成編程,虛擬碼如下:

    百分制轉五分制:   如果成績小於60,轉成“不及格”   如果成績在60與70之間,轉成“及格”   如果成績在70與80之間,轉成“中等”   如果成績在80與90之間,轉成“良好”   如果成績在90與100之間,轉成“優秀”   其他,轉成“錯誤”
  • 可見使用語言簡潔明了,隨後將虛擬碼轉為產品代碼即可。

  • 產品代碼:用以實現特定功能的程式或機器語言。

    public class MyUtil{public static String percentage2fivegrade(int grade){    //如果成績小於0,轉成“錯誤”    if ((grade < 0))        return "錯誤";        //如果成績小於60,轉成“不及格”    else if (grade < 60)        return "不及格";        //如果成績在60與70之間,轉成“及格”    else if (grade < 70)        return "及格";        //如果成績在70與80之間,轉成“中等”    else if (grade < 80)        return "中等";        //如果成績在80與90之間,轉成“良好”    else if (grade < 90)        return "良好";        //如果成績在90與100之間,轉成“優秀”    else if (grade <= 100)        return "優秀";        //如果成績大於100,轉成“錯誤”    else        return "錯誤";}}
  • 寫了產品代碼後,我們還要寫測試代碼,證明自己的代碼沒有問題,這樣才能將代碼放心交到使用者手中。

  • 測試代碼:用以對產品代碼進行測試的代碼。

    public class MyUtilTest {public static void main(String[] args) {    // 百分製成績是50時應該返回五級制的“不及格”    if(MyUtil.percentage2fivegrade(50) != "不及格")        System.out.println("test failed!");    else         System.out.println("test passed!");}}
  • 運行結果如下:

  • 成功了。

  • 不過只測一組就是有偷懶嫌疑了,現在我們把一般情況都試一下:

  • 也成功了

  • 再看看異常情況下的測試:

  • 這時我們發現了程式bug:判斷不及格時沒有要求成績大於零,於是我們修改原始碼,增加對負分的判斷:

    public class MyUtil{   public static String percentage2fivegrade(int grade){   //如果成績小於0,轉成“錯誤”   if ((grade < 0))       return "錯誤";   //如果成績小於60,轉成“不及格”   else if (grade < 60)       return "不及格";   //如果成績在60與70之間,轉成“及格”   else if (grade < 70)       return "及格";   //如果成績在70與80之間,轉成“中等”   else if (grade < 80)       return "中等";   //如果成績在80與90之間,轉成“良好”   else if (grade < 90)       return "良好";   //如果成績在90與100之間,轉成“優秀”   else if (grade < 100)       return "優秀";   //如果成績大於100,轉成“錯誤”   else       return "錯誤";   }}
  • 這時候再重新測一下異常,發現通過了:

  • 可喜可賀。
  • 但是我們還沒有測試邊界情況,於是我們再對輸入為“0,60,70,80,90,100”這些邊界情況進行測試的代碼如下:

    public class MyUtilTest {public static void main(String[] args) {    //測試邊界情況    if(MyUtil.percentage2fivegrade(0) != "不及格")        System.out.println("test failed 1!");    else if(MyUtil.percentage2fivegrade(60) != "及格")        System.out.println("test failed 2!");    else if(MyUtil.percentage2fivegrade(70) != "中等")        System.out.println("test failed 3!");    else if(MyUtil.percentage2fivegrade(80) != "良好")        System.out.println("test failed 4!");    else if(MyUtil.percentage2fivegrade(90) != "優秀")        System.out.println("test failed 5!");    else if(MyUtil.percentage2fivegrade(100) != "優秀")        System.out.println("test failed 6!");    else         System.out.println("test passed!"); }}
  • 結果如預期般出錯了:

  • 於是我們再把原始碼改成了"<=":

    public class MyUtil{   public static String percentage2fivegrade(int grade){   //如果成績小於0,轉成“錯誤”   if ((grade < 0))       return "錯誤";   //如果成績小於60,轉成“不及格”   else if (grade < 60)       return "不及格";   //如果成績在60與70之間,轉成“及格”   else if (grade < 70)       return "及格";   //如果成績在70與80之間,轉成“中等”   else if (grade < 80)       return "中等";   //如果成績在80與90之間,轉成“良好”   else if (grade < 90)       return "良好";   //如果成績在90與100之間,轉成“優秀”   else if (grade <= 100)       return "優秀";   //如果成績大於100,轉成“錯誤”   else       return "錯誤";   }}
  • 再測試一下:

  • 成功了。

  • 值得一提的是,Java中有單元測試工具JUnit來輔助進行TDD。

    錯誤來的太突然:
  • 按照老師給的步驟來走不小心就出現,以為是網路問題,結果換了網也沒有用:

  • 然後試著什麼也不輸入直接點Browse repositories...,然後成功了。
  • 接下來點擊綠色的那個安裝,又出錯了:

  • 氣死了,再下一次,發現他又好了...

  • 回到原題。

  • 從網上下了一個everything用於尋找junit.jar。

  • 然後用老師給的新方法去測試了一下之前的代碼:

  • 成功了,然後可能是版本問題,我的小綠條變成了小綠勾。

  • 其實之前按照攻略來是失敗了的,不過還好有好看的助教學姐指點了我一下,才順利完成測試。

使用StarUML對實驗二中的代碼進行建模
  • 物件導向(Object-Oriented)的三要素包括:封裝、繼承、多態。物件導向的思想涉及到軟體開發的各個方面,如物件導向分析(OOA)、物件導向設計(OOD)、物件導向編程實現(OOP)。OOA根據抽象關鍵的問題域來分解系統,關注是什麼(what)。OOD是一種提供符號設計系統的物件導向的實現過程,用非常接近問題域術語的方法把系統構造成“現實世界”的對象,關注怎麼做(how),通過模型來實現功能規格。OOP則在設計的基礎上用程式設計語言(如Java)編碼。貫穿OOA、OOD和OOP的主線正是抽象。

  • 抽象:即“求同存異、去粗取精”的過程。將若干事物中相同的部分進行剝離整理,並形成具有某特定功能的產品,這一過程即為抽象。過程抽象的結果是函數,資料抽象的結果是抽象資料類型其顯而易見的好處是(在程式設計中)減少了代碼大重複性,提高了效率。

  • 封裝:將與某一將資料與相關行為封裝在一起以實現資訊就隱藏,核心內容是模組化和資訊隱藏,與此相伴的是介面的使用。

  • 封裝:

    public class Dog {private String color;public String getColor() {return color;}public void setColor(String color) {this.color = color;}public String bark(){return "汪汪";}public String toString(){return "The Dog‘s color is " + this.getColor() +", and it shouts "+ this.bark() + "!";}}
  • 檢測:

    public class DogTest {public static void main(String[] args) {Dog d = new Dog();d.setColor("Yellow");getInfo(d);}public static void getInfo(Dog d) {System.out.println(d.toString());}}
  • 是我用starUML弄出來的建模(自學軟體真的很累哦):

以TDD的方式研究學習StringBuffer
  • 關於StringBuffer的代碼如下:
public class StringBufferDemo {  public static void main(String [] args) {    StringBuffer buffer = new StringBuffer();    buffer.append(‘S‘);    buffer.append("tringBuffer");    System.out.println(buffer.charAt(i));    System.out.println(buffer.capacity());    System.out.println(buffer.length());    System.out.println(buffer.indexOf("tring"));    System.out.println("buffer = " + buffer.toString());  }} 
  • 然而老師說這個代碼不可以直接用,在我把第七行的括弧加上後,便完美運行了。

  • 在老師給出的使用JUnit學習Java中,有四個需要我們去測試的東西:charAt()、capacity()、length()和indexOf。

  • 基於以上,我們的測試代碼可為:

    import junit.framework.TestCase;import org.junit.Test;public class StringBufferDemoTest extends TestCase {StringBuffer a = new StringBuffer("StringBuffer");StringBuffer b = new StringBuffer("StringBufferStringBuffer");StringBuffer c = new StringBuffer("StringBufferStringBufferStringBuffer");@Testpublic void testcharAt() {    assertEquals(‘S‘,a.charAt(0));    assertEquals(‘e‘,b.charAt(10));    assertEquals(‘f‘,c.charAt(20));;}@Testpublic void testcapacity() {    assertEquals(28,a.capacity());    assertEquals(40,b.capacity());    assertEquals(52,c.capacity());}@Testpublic void testindexOf() {    assertEquals(0,a.indexOf("Str"));    assertEquals(3,b.indexOf("ing"));    assertEquals(10,c.indexOf("er"));}@Testpublic void testlength() {    assertEquals(12,a.length());    assertEquals(24,b.length());    assertEquals(48,c.length());}}
  • 理所當然的我們測試一下:

  • 成功了。
S.O.L.I.D原則
  • SRP(Single Responsibility Principle,單一職責原則)
    對象提供單一職責的高度封裝,對象的改變僅僅依賴於單一職責的改變

  • OCP(Open-Closed Principle,開放-封閉原則)
    即對擴充開放(功能可增加),對修改封閉(原始碼不可改動)

  • OCP實現手段:(1)抽象和繼承,(2)面向介面編程
    LSP(Liskov Substitusion Principle,Liskov替換原則)
    子類必須可以被其基類所代,父類型對象可以被子類型對象所取代
    ISP(Interface Segregation Principle,介面分離原則)
    客戶不應該依賴他們並未使用的介面

  • DIP(Dependency Inversion Principle,依賴倒置原則)

  • 樣本如下(自己學號%6取餘):

abstract class Data {    abstract public void DisplayValue();}class Integer extends  Data {    int value;    Integer() {        value=100;    }    public void DisplayValue(){        System.out.println (value);    }}class Short extends Data {    short value;    Short() {        value = 5225;    }    public void DisplayValue(){        System.out.println (value);    }}abstract class Factory {    abstract public Data CreateDataObject();}class IntFactory extends Factory {    public Data CreateDataObject(){        return new Integer();    }}class ShortFactory extends Factory {    public Data CreateDataObject(){        return new Short();    }}class Document {    Data pd;    Document(Factory pf){        pd = pf.CreateDataObject();    }    public void DisplayData(){        pd.DisplayValue();    }}public class MyDoc {    static Document d;    public static void main(String[] args) {        d = new Document(new ShortFactory());        d.DisplayData();    }}
  • 這是一個支援short類的代碼,關於學號取餘,若想改成其他,只需要改一下這裡:
class ??? extends Data {    short value;    Short() {        value = 5225;    }    public void DisplayValue(){        System.out.println (value);    }}class ???Factory extends Factory {    public Data CreateDataObject(){        return new ???();    }}public class MyDoc {    static Document d;    public static void main(String[] args) {        d = new Document(new ???Factory());        d.DisplayData();    }}
  • 這樣一來代碼便符合了OCP原則,使代碼有良好的可擴充性、可維護性。
練習:使用TDD的方式設計關實現複數類Complex
  • 虛擬碼:
Complex類要輸出實部,輸出虛部,並按照a+bi的形式輸出複數。Complex類中有兩個變數,實部RealPart和虛部ImaginePart;,double RealPart;複數的實部double ImagePart;複數的虛部getRealPart():返回複數的實部getImagePart();返回複數的虛部setRealPart():設定複數的實部setImagePart();設定複數的虛部輸出形式:a+bi(2)方法:// 定義建構函式public Complex()public Complex(double R,double I)// 定義公有方法:加減乘除Complex ComplexAdd(Complex a) 加Complex ComplexSub(Complex a) 減Complex ComplexMulti(Complex a) 乘Complex ComplexDiv(Complex a) 除//Override Objectpublic boolean equals(Object obj)public String toString():將複數輸出成a+bi的格式。
  • 將其轉換成產品代碼:
import java.util.Scanner;public class MyComplex {    static int r;    static int i;    private double m;    private double n;    public static int getRealPart(int RealPart){        r = RealPart;        return r;    }    public static int getImaginePart(int ImaginePart){        i = ImaginePart;        return i;    }    public MyComplex(double m, double n) {        this.m = m;        this.n = n;    }    public MyComplex add(MyComplex c) {        return new MyComplex(m + c.m, n + c.n);    }    public MyComplex minus(MyComplex c) {        return new MyComplex(m - c.m, n - c.n);    }    public MyComplex multiply(MyComplex c) {        return new MyComplex(m * c.m - n * c.n, m * c.n + n * c.m);    }    public String toString() {        String s = "";        if (n > 0)            s = "(" + m + "+" + n + "i" + ")";        if (n == 0)            s = "(" + m + ")";        if (n < 0)            s = "(" + m + n + "i" + ")";        return s;    }}
  • 測試代碼可為:
import org.junit.Test;import static org.junit.Assert.*;public class MyComplexTest {    MyComplex a=new MyComplex(1,2);    MyComplex b=new MyComplex(1,-4);    MyComplex c=new MyComplex(19,0);    MyComplex d=new MyComplex(0,-3);    MyComplex e=new MyComplex(0,0);    @Test    public void getRealPart() throws Exception {        assertEquals(1, MyComplex.getRealPart(1));        assertEquals(-1, MyComplex.getRealPart(-1));        assertEquals(5, MyComplex.getRealPart(5));        assertEquals(22, MyComplex.getRealPart(22));        assertEquals(-100, MyComplex.getRealPart(-100));        assertEquals(0, MyComplex.getRealPart(0));    }    @Test    public void getImaginePart() throws Exception {        assertEquals(1, MyComplex.getImaginePart(1));        assertEquals(-1, MyComplex.getImaginePart(-1));        assertEquals(5, MyComplex.getImaginePart(5));        assertEquals(22, MyComplex.getImaginePart(22));        assertEquals(-100, MyComplex.getImaginePart(-100));        assertEquals(0, MyComplex.getImaginePart(0));    }    @Test    public void add() throws Exception {        assertEquals("(2.0-2.0i)", a.add(b).toString());        assertEquals("(20.0+2.0i)", a.add(c).toString());        assertEquals("(1.0-1.0i)", a.add(d).toString());        assertEquals("(1.0+2.0i)", a.add(e).toString());    }    @Test    public void minus() throws Exception {        assertEquals("(0.0+6.0i)", a.minus(b).toString());        assertEquals("(-18.0+2.0i)", a.minus(c).toString());        assertEquals("(1.0+5.0i)", a.minus(d).toString());        assertEquals("(1.0+2.0i)", a.minus(e).toString());    }    @Test    public void multiply() throws Exception {        assertEquals("(9.0-2.0i)", a.multiply(b).toString());        assertEquals("(19.0+38.0i)", a.multiply(c).toString());        assertEquals("(6.0-3.0i)", a.multiply(d).toString());        assertEquals("(0.0)", a.multiply(e).toString());    }}
  • 測試成功:

實驗體會與總結
  • 說實話,這次實驗要我編程我是不會編的..但是還好老師給了模板,只需要改一下就好了。

  • 在實驗有了代碼支撐後,比較累的地方就是要看好多好多長部落格,還有以上提到的一些軟體的操作方法你都要學(雖然老師有給出UML的另一個建模方法,但是我還是用了別的)。

  • 值得一提的是,這次學到的東西能讓我更輕鬆的去修正代碼bug,減少了之後修複所需要的大量精力。

  • 但是不管怎麼說,過程還是很累的,有時候都想把部落格全部關掉,好好睡一下,好在最後我寫完了。

  • 還是要繼續加油呀!

  • 碼雲連結(這也是我第一次規範書寫git傳代碼哦)

實驗二 Java物件導向程式設計

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.