java面相对象程序设计_20165235 实验二Java面向对象程序设计

这篇博客介绍了Java面向对象程序设计的实践,包括单元测试、TDD(测试驱动开发)的应用以及SOLID原则的理解。作者展示了如何编写和测试百分制转五分制的函数,使用JUnit进行单元测试,以及在不同场景下测试代码的正确性。此外,还探讨了在需求变更时如何遵循OCP原则进行代码扩展。最后,通过一个复数类的实现,进一步阐述了TDD的过程,包括类的设计、测试用例的编写以及相关问题的解决方法。
摘要由CSDN通过智能技术生成

20165235 Java面向对象程序设计

姓名:祁瑛

学号:20165235

班级:1652

实验课程:JAVA程序设计

实验名称:Java面向对象程序设计

实验时间:2018.4.14

指导老师:娄家鹏

一,实验内容及步骤

面向对象程序设计-1

单元测试:这里我们设计了一个测试用例(Test Case),测试用例是为某个特殊目标而编制的一组测试输入、执行条件以及预期结果,以便测试某个程序路径或核实是否满足某个特定需求。在运行程序时可以找到bug。

在本次实验中我的产品代码如下:

public class MyUtil1{

public static String percentage2fivegrade(int grade){

if ((grade < 0))

return "错误";

else if (grade < 60)

return "不及格";

else if (grade < 70)

return "及格";

else if (grade < 80)

return "中等";

else if (grade < 90)

return "良好";

else if (grade <= 100)

return "优秀";

else

return "错误";

}

}

测试代码:

1.正常情况:

e6609c9eab8b5ff1fdfd36caef7422a3.png

public class MyUtilTest {

public static void main(String[] args) {

//测试正常情况

if(MyUtil.percentage2fivegrade(55) != "不及格")

System.out.println("test failed 1!");

else if(MyUtil.percentage2fivegrade(65) != "及格")

System.out.println("test failed 2!");

else if(MyUtil.percentage2fivegrade(75) != "中等")

System.out.println("test failed 3!");

else if(MyUtil.percentage2fivegrade(85) != "良好")

System.out.println("test failed 4!");

else if(MyUtil.percentage2fivegrade(95) != "优秀")

System.out.println("test failed 5!");

}

}

测试图:

2.非正常情况测试代码:

public class MyUtilTest {

public static void main(String[] args) {

//测试出错情况

if(MyUtil.percentage2fivegrade(-10) != "错误")

System.out.println("test failed 1!");

else if(MyUtil.percentage2fivegrade(115) != "错误")

System.out.println("test failed 2!");

else

System.out.println("test passed!");

}

}

测试图:

3f119b848bdfb4bc9c6abcc128efc197.png

Java中有单元测试工具JUnit来辅助进行TDD,我们用TDD的方式把前面百分制转五分制的例子重写一次。

TDD的测试步骤如下:

明确当前要完成的功能,记录成一个测试列表

快速完成编写针对此功能的测试用例

测试代码编译不通过(没产品代码呢)

编写产品代码

测试通过

对代码进行重构,并保证测试通过(重构下次实验练习)

循环完成所有功能的开发

以下是测试代码:

import org.junit.Test;

import junit.framework.TestCase;

public class MyUtilTest extends TestCase {

@Test

public void testNormal() {

assertEquals("不及格", MyUtil1.percentage2fivegrade(55));

assertEquals("及格", MyUtil1.percentage2fivegrade(65));

assertEquals("中等", MyUtil1.percentage2fivegrade(75));

assertEquals("良好", MyUtil1.percentage2fivegrade(85));

assertEquals("优秀", MyUtil1.percentage2fivegrade(95));

}

@Test

public void testAbnormal() {

assertEquals("错误", MyUtil1.percentage2fivegrade(-55));

assertEquals("错误", MyUtil1.percentage2fivegrade(155));

}

@Test

public void testBorder() {

assertEquals("不及格", MyUtil1.percentage2fivegrade(0));

assertEquals("及格", MyUtil1.percentage2fivegrade(60));

assertEquals("中等", MyUtil1.percentage2fivegrade(70));

assertEquals("良好", MyUtil1.percentage2fivegrade(80));

assertEquals("优秀", MyUtil1.percentage2fivegrade(90));

assertEquals("优秀", MyUtil1.percentage2fivegrade(100));

}

}

测试图如下:

003a2b6813597539314433561807264e.png

当JUnit出现绿条说明测试成功。

面向对象程序设计-2

对于这个程序,需要测试的方法有四个,charAt()、capacity()、length()、indexOf。而且要对老师博客中给出的代码进行改写,对测试的方法要加上返回值,便于我们测试。

-以下是TDD的方式研究学习StringBuffer

public class StringBufferDemo{

StringBuffer buffer = new StringBuffer();

public StringBufferDemo(StringBuffer buffer){

this.buffer = buffer;

}

public Character charAt(int i){

return buffer.charAt(i);

}

public int capacity(){

return buffer.capacity();

}

public int length(){

return buffer.length();

}

public int indexOf(String str) {

return buffer.indexOf(str);

}

}

而且有必要了解以下上面四个方法的作用:

charAt(int n):返回指定字符在字符串中的位置。

indexOf(String s):返回输入的子字符串的第一个字母在母字符串的位置

capacity():是当前实体的实际容量。

length():实体中存放的字符序列的长度。

有了初步的了解后就可以进行测试了,以下是测试代码:

import junit.framework.TestCase;

import org.junit.Test;

public class StringBufferDemoTest extends TestCase {

StringBuffer str1 = new StringBuffer("StringBuffer");

StringBuffer str2 = new StringBuffer("StringBufferStringBuffer");

StringBuffer str3 = new StringBuffer("StringBufferStringBufferStringBuffer");

@Test

public void testcharAt() throws Exception{

assertEquals('S',str1.charAt(0));

assertEquals('g',str1.charAt(5));

assertEquals('r',str1.charAt(11));

}

@Test

public void testcapacity() throws Exception{

assertEquals(28,str1.capacity());

assertEquals(40,str2.capacity());

assertEquals(52,str3.capacity());

}

@Test

public void testlength() throws Exception{

assertEquals(12,str1.length());

assertEquals(24,str2.length());

assertEquals(36,str3.length());

}

@Test

public void testindexOf() throws Exception{

assertEquals(0,str1.indexOf("Str"));

assertEquals(5,str2.indexOf("gBu"));

assertEquals(10,str3.indexOf("er"));

}

}

以下是测试图:

e139ed5bff7e151e49fd53e9f7c4b540.png

面向对象程序设计-3

设计应该满足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,依赖倒置原则)

老师给出的代码是实现返回int类,题目要求给出返回long类,如果对代码直接进行删改就违反了OCP原则,对增加开放,对删除封闭。所以要使用设计模式了。使用面向接口编程,使用抽象和继承。以下是实验任务:

用自己的学号%6进行取余运算,根据结果进行代码扩充:

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

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

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

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

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

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

对代码只需要增加class Long extends Data、class LongFactory extends Factory即可使系统支持Long类型。以下是测试代码:

abstract class Data{

public abstract void DisplayValue();

}

class Integer extends Data {

int value;

Integer(){

value=100;

}

public void DisplayValue(){

System.out.println(value);

}

}

class Long extends Data {

long value;

Long(){

value=20165235l;

}

public void DisplayValue(){

System.out.println(value);

}

}

class Float extends Data {

float value;

Float(){

value=2.0165235F;

}

public void DisplayValue(){

System.out.println(value);

}

}

class Document {

Data pd;

Document(Factory pf){

pd = pf.CreateDataObject();

}

public void DisplayData(){

pd.DisplayValue();

}

}

abstract class Factory {

abstract public Data CreateDataObject();

}

class IntFactory extends Factory {

public Data CreateDataObject(){

return new Integer();

}

}

class LongFactory extends Factory {

public Data CreateDataObject(){

return new Float();

}

}

class FloatFactory extends Factory {

public Data CreateDataObject(){

return new Float();

}

}

public class MyDoc {

static Document d;

public static void main(String[] args) {

d = new Document(new FloatFactory());

d.DisplayData();

}

}

而且我在程序里不仅实现返回long类而且实现了返回Float类,步骤如同上。

测试图:

00940a7a6cf0757d18d6a0f339ebb606.png

e8324fcf6309bf974edb151a47fb077e.png

而且我使用了starMUL软件对本次程序代码进行建模。使用程序步骤如下:

首先打开starMUL,如下图点击

191aeb1ab7cb8ed89947d8728cd140bf.png

在左侧的ToolBox中选择画图工具

5a2073a0ae2dac141febbe65e21295a9.png

在右侧的文件管理中可以进行删除等操作

7e15a84073b17cc1b3a5546e217c3402.png

这次实验的MUL图:

b8c2fdfce716c217ab0fc31e734e5152.png

面向对象程序设计-4

本次实验任务:

使用TDD的方式设计关实现复数类Complex

// 定义属性并生成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)

首先应该是写伪代码:

在Complex类中设置构造方法public Complex()

public Complex(double R,double I)

设置实部与虚部double RealPart;

double ImagePart;

设置返回实部与虚部的方法

实现加法Complex ComplexAdd(Complex a)

实现减法Complex ComplexSub(Complex a)

实现乘法Complex ComplexMulti(Complex a)

实现除法Complex ComplexDiv(Complex a)

重写toString()方法

重写equals()方法

有了伪代码就可以写产品代码了:

public class Complex {

double R;//复数的实部

double I;//复数的虚部

Complex(double R, double I) {

this.R = R;

this.I = I;

}

public static double getRealPart(double R) { //返回复数的实部

return R;

}

public static double getImagePart(double I) { //返回复数的虚部

return I;

}

public Complex ComplexAdd(Complex c) {//加法运算

return new Complex(R + c.R, I + c.I);

}

public Complex ComplexSub(Complex c) {//减法运算

return new Complex(R - c.R, I - c.I);

}

public Complex ComplexMulti(Complex c) {//乘法运算

return new Complex(R * c.R - I * c.I, R * c.I + I * c.R);

}

public Complex ComplexDiv(Complex c) {//除法运算

return new Complex((R * c.I + I * c.R) / (c.I * c.I + c.R * c.R), (I * c.I + R * c.R) / (c.I * c.I + c.R * c.R));

}

public String toString() {//重写toString方法

String str = "";

if (I > 0)

str = R + "+" + I + "i";

if (I == 0)

str = R+"";

if (I < 0)

str = R + "" + I + "i";

return str;

}

public boolean equals(Object obj){//重写equals方法

if (this == obj)

return true;

if(obj==null)

return false;

if(obj instanceof Complex){

Complex p = (Complex) obj;

if(p.R==this.R &&p.I==this.I )

return true;

}

return false;

}

}

以下是测试代码:

import junit.framework.TestCase;

import org.junit.Test;

public class ComplexTestTest extends TestCase {

Complex c1 = new Complex(1.0,2.0);

Complex c2 = new Complex(2.0,2.0);

Complex c3 = new Complex(2.0,0.0);

@Test

public void testGetRealPart() throws Exception {

assertEquals(-1.1, Complex.getRealPart(-1.1));

assertEquals(6.0, Complex.getRealPart(6.0));

assertEquals(0.0, Complex.getRealPart(0.0));

}

@Test

public void testGetImagePart() throws Exception {

assertEquals(-1.1, Complex.getImagePart(-1.1));

assertEquals(6.0, Complex.getImagePart(6.0));

assertEquals(0.0, Complex.getImagePart(0.0));

}

@Test

public void testComplexAdd() throws Exception {

assertEquals("3.0+4.0i", c1.ComplexAdd(c2).toString());

assertEquals("3.0+2.0i", c1.ComplexAdd(c3).toString());

assertEquals("4.0+2.0i", c2.ComplexAdd(c3).toString());

}

@Test

public void testComplexSub() throws Exception {

assertEquals("-1.0", c1.ComplexSub(c2).toString());

assertEquals("-1.0+2.0i", c1.ComplexSub(c3).toString());

assertEquals("0.0+2.0i", c2.ComplexSub(c3).toString());

}

@Test

public void testComplexMulti() throws Exception {

assertEquals("-2.0+6.0i", c1.ComplexMulti(c2).toString());

assertEquals("2.0+4.0i", c1.ComplexMulti(c3).toString());

assertEquals("4.0+4.0i", c2.ComplexMulti(c3).toString());

}

@Test

public void testComplexComplexDiv() throws Exception {

assertEquals("0.75+0.75i", c1.ComplexDiv(c2).toString());

assertEquals("1.0+0.5i", c1.ComplexDiv(c3).toString());

assertEquals("1.0+1.0i", c2.ComplexDiv(c3).toString());

}

@Test

public void testEquals() throws Exception{

assertEquals(false,c1.equals(c2));

assertEquals(false,c1.equals(c3));

assertEquals(false,c2.equals(c3));

assertEquals(true,c1.equals(c1));

}

}

测试图如下:

c070c5d282d2eff5e98c409c38aaff83.png

实验过程中遇到的问题及解决

问题一:使用ieda时显示无法加载到主类:

如图:

cf104a63b5b4f6f8de1d68816c1e8dde.png

解决方法:点右上方的main,:

2760f5e235a42d7eeb0c323fcf1e8773.png

-点Edit configurations, 把Name和Main class名称改了就行。

9e47afc4fbe71fd23afb397ff4a9405d.png

问题二:junit包导入了,为什么@Test还是红的

解决方法:点击代码旁的小灯泡然后点击Convert to Junit4 Test case

d0ee237bef739041b230df25eeba2996.png

问题三:一直找不到JunitGeneratorV2.0的下载路径

解决方法:打开plugins,点击下面的browse

2d883d3a0c558654fe2f9f65da817584.png

然后检索Junit就可以找出来

39b4248d4de6116655755e06faecfcd0.png

问题四:一直找不到junit的路径。

解决方法:可以直接在盘里搜关键字junit就可以搜出来。

5db8d15e5f2f3589d431a97cc9e59906.png

实验感想

本周的实验比较多但主旨相对集中:面向对象编程和TDD的使用。对于面向对象编程要满足三要素:封装,继承与多态。想要更好的了解这些属性我感觉灵活的使用starMUL建模是个不错的方法。灵活的使用设计模式也很重要,对于设计模式要满足S.O.L.I.D原则,本次着重学习的是S.O.L.I.D中的OCP原则。设计完程序后又要新的需求但是不能删改代码,这里就要使用到设计模式,对增加代码开放,对删改进行封闭,这一原则不仅有益于实现需求,更能减少程序的bug。在Java语言中,可以通过JUnit框架进行单元测试,通过单元测试可以减少代码的bug,提高代码的质量。

步骤

耗时

百分比

需求分析

20min

8%

设计

60min

25%

代码实现

120min

50%

测试

10min

4%

分析总结

30min

13%

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值