Java实验二
一,实验内容
1. 初步掌握单元测试和TDD
2. 理解并掌握面向对象三要素:封装、继承、多态
3. 初步掌握UML建模
4. 熟悉S.O.L.I.D原则
5. 了解设计模式
二,实验步骤
(一)单元测试
(1) 三种代码
伪代码:对程序作用或功能的解释
产品代码:同特定的编程语言编写的可实现一定功能的代码
测试代码:用来检测产品代码是否有漏洞,或程序是否满足某个特定需求
(2)TDD(Test Driven Devlopment,测试驱动开发)
测试驱动开发(TDD):先写测试代码,再写产品代码,从而写出来的代码就是正确的
步骤如下:
明确当前要完成的功能,记录成一个测试列表
快速完成编写针对此功能的测试用例
测试代码编译不通过
编写产品代码
对代码进行重构,并保证测试通过
循环完成所有功能的开发
具体百分制转五分制实例如下:
测试代码MyUtilTest
package ag20159201;
import junit.framework.TestCase;
import org.junit.Test;
public class MyUtilTest extends TestCase {
@Test
public void testNormal() {
assertEquals("不及格", MyUtil.percentage2fivegrade(55));
assertEquals("及格", MyUtil.percentage2fivegrade(65));
assertEquals("中等", MyUtil.percentage2fivegrade(75));
assertEquals("良好", MyUtil.percentage2fivegrade(85));
assertEquals("优秀", MyUtil.percentage2fivegrade(95));
}
public void testException() {
assertEquals("错误", MyUtil.percentage2fivegrade(101));
assertEquals("错误", MyUtil.percentage2fivegrade(-51));
}
public void testBoundary() {
assertEquals("不及格", MyUtil.percentage2fivegrade(0));
assertEquals("及格", MyUtil.percentage2fivegrade(60));
assertEquals("中等", MyUtil.percentage2fivegrade(70));
assertEquals("良好", MyUtil.percentage2fivegrade(80));
assertEquals("优秀", MyUtil.percentage2fivegrade(90));
assertEquals("优秀", MyUtil.percentage2fivegrade(100));
}
}
产品代码MyUtil
package ag20159201;
public class MyUtil {
public static String percentage2fivegrade ( int grad){
if (grad<0)
return "错误";
else if (grad<60)
return "不及格";
else if (grad<70)
return "及格";
else if (grad<80)
return "中等";
else if (grad<90)
return "良好";
else if (grad<=100)
return "优秀";
else return "错误";
}
}
使用驱动开发后的测试结果
(二)继承封装多态
面向对象(Object-Oriented)的三要素包括:封装、继承、多态。过程抽象的结果是函数,数据抽象的结果是抽象数据类型。封装实际上使用方法(method)将类的数据隐藏起来,控制用户对类的修改和访问数据的程度,从而带来模块化(Modularity)和信息隐藏(Information hiding)的好处;接口(interface)是封装的准确描述手段。封装类型包括:
1、 封装对象初始流程:用构造函数。构造函数是与类名称同名的方法,不用声明返回类型;
2、 封装对象操作流程:在类中添加方法,以实现特定功能;方法名称首写字母为小写;
3、 封装对象内部数据:定义private变量,是用户必须使用程序员自定义的操作流程。控制用户对类的修改和访问数据的程度,
package ag20159201;
public abstract class Animal {
private String color;
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public abstract String shout();
}
继承与多态:Java中使用关键字extends,private成员也会被继承,只是子类无法直接存取,必须通过父类提供的方法来存取。多态就是单一接口操作多种类型的对象。
package ag20159201;
public class Dog extends Animal{
public String shout(){
return "汪汪";
}
public String toString(){
return "The Dog's color is " + this.getColor() +", and it shouts "+ this.shout() + "!";
}
}
package ag20159201;
public class Cat extends Animal{
public String shout(){
return "喵喵";
}
public String toString(){
return "The Cat's color is " + this.getColor() +", and it shouts "+ this.shout() + "!";
}
}
测试代码及结果如下:
(三)使用TDD的方式设计关实现复数类Complex
伪代码:
首先设计一个复数类Complex,定义三个构造方法:
①没有参数时默认为实部和虚部都为0;
②一个参数时默认为实数,即虚部为0,
③两个参数时分别为实部和虚部
再定义两个成员方法计算两个复数的和与差.定义一个print()方法输出复数的值,当虚部为0时不输出虚部.
最后定义一个ComplexTest类使用Complex类,在这个类的主方法中创建两个复数对象,分别计算这两个复数的和与差并输出.
产品代码:
package ag20159201;public classComplex
{doublerePart,imPart;
Complex()
{this.rePart=0;this.imPart=0;
}
Complex(doublerePart)
{this.rePart=rePart;this.imPart=0;
}
Complex(double rePart,doubleimPart)
{this.rePart=rePart;this.imPart=imPart;
}staticComplex Add(Complex p1,Complex p2)
{
Complex p=new Complex(p1.rePart+p2.rePart,p1.imPart+p2.imPart);returnp;
}
Complex Min(Complex p1,Complex p2)
{
Complex p=new Complex(p1.rePart-p2.rePart,p1.imPart-p2.imPart);returnp;
}voidPrint()
{
System.out.println("复数的值为:");if(this.imPart!=0)
System.out.println("("+this.rePart+","+this.imPart+")");else System.out.println(this.rePart);
}
}
测试代码及结果:
步骤
耗时
百分比
需求分析
0.5h
10%
设计
1h
20%
代码实现
1.5h
30%
测试
1h
20%
分析总结
1h
20%
三、总结
遇到的问题及解决:
1、提示Animal代码有错,Dog和Cat需要在文件中被定义,于是将Animal和Dog、Cat放在不同的class文件中编译。程序依然报错,原因是三个文件在不同的里包,可以通过把它们放同一个包或是在代码前通过import进行路径申明
2、实现Complex复数类函数时想在ComplexTest函数中也使用assertEquals()来进行电脑自动测试,但是程序报错,只好通过函数输出的方式人工检验。希望在今后的学习中找到更好的方法
3、对Java不了解,编程出现错误很多,改代码十分费劲。要通过程序和书本知识不断结合才能更好学习
收获:
认识到Java语言面向对象编程的特点,如封装继承多态,接口和多态,这些和C语言有相似的地方,也有Java自己的特色,值得深入学习。但自己刚刚接触但Java,很多地方了解不深,以后要走的路还很长。