2018-2019-2 20175217 实验二《Java面向对象程序设计》实验报告

一、实验报告封面

  • 课程:Java程序设计 班级:1752班 姓名:吴一凡 学号:20175217
  • 指导教师:娄嘉鹏 实验日期:2019年4月15日
  • 实验时间:--- 实验序号:实验二
  • 实验名称:Java开发环境的熟悉
  • 实验题目:
  • 实验要求:
    • 完成实验二《Java面向对象程序设计》中的内容
    • 其中Eclipse相关的内容参考Intellj IDEA 简易教程换成IDEA实现
    • 参考实验二《Java面向对象程序设计》的一点说明,完成云班课中的检查点,也可以先完成实验报告,直接提交。注意不能只有截图,要有知识点,原理,遇到的问题和解决过程等说明。实验报告中一个检
    • 查点要有多张截图。
    • 发表实验报告博客,标题“学期(如2018-2019-2) 学号(如20175300)实验二《Java面向对象程序设计》实验报告”

二、实验步骤

1.单元测试——对类实现测试

  • 点击New->Directory新建一个test目录,再右键点击设置环境变量,选择Mark Directory->Test Sources Root

  • 分别对“正常情况”、“边界情况”、“异常情况”进行检验

    • 正常情况:

    • 边界情况:

    • 异常情况:

  • 根据上述检验结果对代码进行修改,直至三种检验情况都通过

2.以TDD的方式研究学习StringBuffer

1.TDD的一般步骤

  • 明确当前要完成的功能,记录成一个测试列表
  • 快速完成编写针对此功能的测试用例
  • 测试代码编译不通过(没产品代码呢)
  • 编写产品代码
  • 测试通过
  • 对代码进行重构,并保证测试通过(重构下次实验练习)
  • 循环完成所有功能的开发

2.Junit的配置及使用

1.点击File->Project Structure进入配置界面

2.点击这里的加号

3.在路径中选择你安装IDEA的路径,找到里面的lib文件夹,点击其中的Junit即可

4.点击你要测试的类名,再点击右侧的小灯泡,然后点击Create Test

5.这里选择Junit3,下面选择你要测试的方法

6.依次添加正常测试、边界测试、异常测试,使用assertEquals语句测试实际结果与预期结果是否一致,注意测试用例前一定要有注解@Test。

7.根据报错的assert语句改正产品代码,直至最终测试成功

3.StringBuffer

  • capacity返回的是目前的最大容量而length返回的是字符串长度
    • 默认值为16
    • 根据capacity的构造方法```StringBuffer(int capacity),可以指定初始容量

  • charAt返回该位置上的字符:public char charAt(int index)

  • indexOf返回第一次出现的指定子字符串在该字符串中的索引public int indexOf(String str)

  • String类和StringBuffer类的区别

    • String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低下,而且大量浪费有限的内存空间。
    • StringBuffer和StringBuilder类功能基本相似,主要区别在于StringBuffer类的方法是多线程、安全的,而StringBuilder不是线程安全的,相比而言,StringBuilder类会略微快一点。对于经常要改变值的字符串应该使用StringBuffer和StringBuilder类。
    • 一般情况下,速度从快到慢:StringBuilder>StringBuffer>String,这种比较是相对的,不是绝对的。
  • 用法总结

    • 如果要操作少量的数据用 = String
    • 单线程操作字符串缓冲区 下操作大量数据 = StringBuilder
    • 多线程操作字符串缓冲区 下操作大量数据 = StringBuffer
  • StringBuffer的测试

4.面向对象三要素

  • 抽象:抽出事物的本质特征而暂不考虑细节,对于复杂的问题分层求解
  • 过程抽象:结果是函数
  • 数据抽象:结果是抽象数据类型
  • 封装,继承与多态(面向对象的三要素)
    • 封装:将数据与相关行为包装在一起以实现信息隐藏,java中使用类进行封装,接口是封装准确描述手段
    • 继承:关键在于确认子类为父类的一个特殊类型,以封装为基础,继承可以实现代码复用,继承更重要的作用是实现多态。
    • 多态:同一消息可以根据发送对象的不同而采用多种不同的行为方式

5.设计模式初步

  • S.O.L.I.D原则

    • SRP(Single Responsibility Principle,单一职责原则)
    • OCP(Open-Closed Principle,开放-封闭原则)
    • 对扩充开放,对修改封闭:抽象和继承;面向接口编程
    • LSP(Liskov Substitusion Principle,Liskov替换原则)
    • ISP(Interface Segregation Principle,接口分离原则)
    • DIP(Dependency Inversion Principle,依赖倒置原则)
  • 设计模式

    • Pattern name:描述模式,便于交流,存档
    • Problem:描述何处应用该模式
    • Solution:描述一个设计的组成元素,不针对特例
    • Consequence:应用该模式的结果和权衡(trade-offs)

3.OCP原则和DIP原则的应用

  • 让系统支持Double类,并在MyDoc类中添加测试代码表明添加正确,提交测试代码和运行结的截图,加上学号水印:

4.以TDD的方式进行开发

  • 伪代码
// 定义属性并生成getter,setter
double RealPart;
double ImagePart;
// 定义构造函数
public Complex()
public Complex(double R,double I)
//Override Object
public boolean equals(Object obj)
public String toString()
// 定义公有方法:加减乘除
Complex ComplexAdd(Complex a)
Complex ComplexSub(Complex a)
Complex ComplexMulti(Complex a)
Complex ComplexDiv(Complex a)
  • 产品代码
import java.lang.Integer;
import java.util.Objects;

public class Complex {
    //定义属性并生成getter,setter
    double RealPart;
    double ImagePart;
    public double getRealPart(){
        return RealPart;
    }
    public double getImagePart(){
        return ImagePart;
    }

    //定义构造函数
    public Complex(){
        RealPart = 0;
        ImagePart = 1;
    }
    public Complex(double R,double I){
        RealPart = R;
        ImagePart = I;
    }

    //Override Object
    public boolean equals(Object obj){
        if(this == obj){
            return true;
        }
        if(!(obj instanceof Complex)) {
            return false;
        }
        Complex complex = (Complex) obj;
        if(complex.RealPart != ((Complex) obj).RealPart) {
            return false;
        }
        if(complex.ImagePart != ((Complex) obj).ImagePart) {
            return false;
        }
        return true;
    }
    public String toString(){
        String s = new String();
        if (ImagePart > 0){
            s = getRealPart() + "+" + getImagePart() + "i";
        }
        if (ImagePart == 0){
            s = getRealPart() + "";
        }
        if(ImagePart < 0){
            s = getRealPart() + "" + getImagePart() + "i";
        }
        if(RealPart == 0){
            s = getImagePart() + "i";
        }
        return s;
    }
    //定义公有方法:加减乘除
    Complex ComplexAdd(Complex a){
        return new Complex(RealPart + a.RealPart,ImagePart + a.ImagePart);
    }
    Complex ComplexSub(Complex a){
        return new Complex(RealPart - a.RealPart,ImagePart - a.ImagePart);
    }
    Complex ComplexMulti(Complex a){
        return new Complex(RealPart*a.RealPart-ImagePart*a.ImagePart,RealPart*a.ImagePart + ImagePart*a.RealPart);
    }
    Complex ComplexDiv(Complex a) {
        return new Complex((RealPart * a.ImagePart + ImagePart * a.RealPart) / (a.ImagePart * a.ImagePart + a.RealPart * a.RealPart), (ImagePart * a.ImagePart + RealPart * a.RealPart) / (a.RealPart * a.RealPart + a.RealPart * a.RealPart));
    }
}
  • 测试代码
import junit.framework.TestCase;
import org.junit.Test;

public class ComplexTest extends TestCase {
    Complex a=new Complex(3.0,4.0);
    Complex b=new Complex(0.0,5.0);
    Complex c=new Complex(-2.0,-3.0);

    @Test
    public void testgetRealpart() throws Exception{
        assertEquals(3.0,a.getRealPart());
        assertEquals(0.0,b.getRealPart());
        assertEquals(-2.0,c.getRealPart());
    }

    @Test
    public void testgetImagePart() throws Exception{
        assertEquals(4.0,a.getImagePart());
        assertEquals(5.0,b.getImagePart());
        assertEquals(-3.0,c.getImagePart());
    }

    @Test
    public void testComplexAdd() throws Exception{
        assertEquals("3.0+9.0i",a.ComplexAdd(b).toString());
        assertEquals("1.0+1.0i",a.ComplexAdd(c).toString());
        assertEquals("-2.0+2.0i",b.ComplexAdd(c).toString());
    }

    @Test
    public void testComplexSub() throws Exception{
        assertEquals("3.0-1.0i",a.ComplexSub(b).toString());
        assertEquals("5.0+7.0i",a.ComplexSub(c).toString());
        assertEquals("2.0+8.0i",b.ComplexSub(c).toString());
    }

    @Test
    public void testComplexMulti() throws Exception{
        assertEquals("-20.0+15.0i",a.ComplexMulti(b).toString());
        assertEquals("6.0-17.0i",a.ComplexMulti(c).toString());
        assertEquals("15.0-10.0i",b.ComplexMulti(c).toString());
    }

    @Test
    public void testComplexDiv() throws Exception{
        assertEquals("0.6+Infinityi",a.ComplexDiv(b).toString());
    }

    @Test
    public void testtoString() throws Exception{
        assertEquals("3.0+4.0i",a.toString());
        assertEquals("5.0i",b.toString());
        assertEquals("-2.0-3.0i",c.toString());
    }
}
  • 运行结果

三、实验类图

四、实验中遇到的问题和解决过程

  • 在刚开始测试MyUtil类时,异常测试出现了问题

  • 新建了一个测试主类,通过debug调试发现问题出在条件设置的错误,改正后最终解决了问题

五、实验感悟

  • 通过本次实验,我主要学会了如何编写测试代码,如何使用UML图,也了解了TDD方式、S.O.L.I.D原则以及设计模式等编程思想,相信这些思想也会对我以后的编程有很大的影响,我也会认真总结、反思本次实验中出现的问题,反复消化理解这些知识的~
posted @ 2019-04-17 11:03  20175217wyf  阅读(319)  评论(0编辑  收藏  举报