20145213《Java程序设计》实验二Java面向对象程序设计实验报告


实验内容

  1. 初步掌握单元测试和TDD
  2. 理解并掌握面向对象三要素:封装,继承,多态
  3. 初步掌握UML建模
  4. 熟悉S.O.L.I.D原则
  5. 了解设计模式

实验步骤

一、 单元测试

  • 三种代码
  1. 伪代码
  2. 产品代码
  3. 测试代码

    伪代码是产品代码最自然、最好的注释。那么什么是伪代码呢?如下图所示:
   如果成绩小于60,转成“不及格”
如果成绩在60与70之间,转成“及格”
如果成绩在70与80之间,转成“中等”
如果成绩在80与90之间,转成“良好”
如果成绩在90与100之间,转成“优秀”
其他,转成“错误”

产品代码就是最终的成品了,编译的过程就是把上述易懂得伪代码翻译成机器语言,让计算机识别并执行。根据上图伪代码可以编译如下产品代码:

public class MyUtil{
public static String percentage2fivegrade(int grade){
//如果成绩小于60,转成“不及格”
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 "优秀";
//其他,转成“错误”
else
return "错误";
}
}

测试代码就是对成品产品代码的验算与检验,证明成品代码没有问题。正对MyUtil我们写一个MyUtilTest.java的测试模块,代码如下:

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!");
}
}

二、 TDD(Test Dirven Development,测试驱动开发)

  • TDD的一般步骤如下:
  1. 明确当前要完成的功能,记录成一个测试列表
  2. 快速完成编写针对此功能的测试用例
  3. 测试代码编译不通过(没产品代码呢)
  4. 编写产品代码
  5. 测试通过
  6. 对代码进行重构,并保证测试通过(重构下次实验联系)
  7. 循环完成所有功能的开发

    基于TDD,我们不会出现过度设计的情况,需求通过测试用例表达出来,我们的产品代码只要让测试通过就可以了。

    就像这样





三、 面向对象三要素

  1. 抽象

    "去粗取精、化繁为简、由表及里、异中求同"。抽象就是抽出事物的本质特征而暂时不考虑他们的细节。对于复杂系统问题人们借助分层次抽象的方法进行问题求解;在抽象的最高层,可以使用问题环境的语言,以概括的方式叙述问题的解。在抽象的较低层,则采用过程化的方式进行描述。在描述问题解时,使用面向问题和面向实现的术语。程序设计中,抽象包括两个方面,一是过程抽象,二是数据抽象。
  2. 封装、继承与多态

    面向对象(Object-Oriented)的三要素包括:封装、继承、多态。过程抽象的结果是函数,数据抽象的结果是抽象数据类型(Abstract Data Type,ADT),类可以作具有继承和多态机制的ADT。数据抽象才是OOP的核心和起源。
  • 构造函数实现对象初始化流程的封装。方法封装了操作对象的流程。Java中还可以用private封装对象私有数据成员。封装的目的主要就是隐藏对象细节,将对象当做黑箱进行操作。实例代码如下:
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() + "!";
}
}
  • 继承基本上就是为了避免多个类间重复定义行为共同行为。子类利用关键词extends继承父类,避免重复的行为定义。实例代码如下:
public abstract class Animal {
private String color;
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public abstract String shout();
}
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() + "!";
}
}
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() + "!";
}
}
  • 多态就是使用单一接口操作多种类型的对象。实例代码如下:
package cc.openhome;
public class RPG {
public static void main(String[] args) {
SwordsMan swordsMan = new SwordsMan();
swordsMan.setName("Justin");
swordsMan.setLevel(1);
swordsMan.setBlood(200);
Magician magician = new Magician();
magician.setName("Monica");
magician.setLevel(1);
magician.setBlood(100);
drawFight(swordsMan);
drawFight(magician);
}
static void drawFight(Role role) {
System.out.print(role.getName());
role.fight();
}
}

四、 UML的使用

给一个代码,很难第一时间了解这个代码的整体结构组成,这时候如果利用StarUML软件进行UML建模,

代码的结构组成,各个类的成员变量就可以一目了然了,想这样









前缀减号的代表是Private,前缀加号的代表public


五、 设计模式与S.O.L.I.D原则

  1. 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,依赖倒置原则)
  2. 设计模式实示例

    设计模式有四个基本要素:

    Pattern name:描述模式,便于交流,存档

    Problem:描述何处应用该模式

    Solution:描述一个设计的组成元素,不针对特例

    Consequence:应用该模式的结果和权衡(trade-offs)

    六、 练习作业(能力有限,代码不是原创,借鉴同学或者百度,具体参见参考资料)

    代码模块介绍
  3. 复数类ComplexNumber的属性

    m_dRealPart: 实部,代表复数的实数部分

    m_dImaginPart: 虚部,代表复数的虚数部分
  4. 复数类ComplexNumber的方法

    ComplexNumber() 构造函数,将实部,虚部都置为0

    ComplexNumber(double r, double I) 构造函数,创建复数对象的同时完成复数的实部,虚部的初始化

    GetRealPart() 获取实部

    GetImaginaryPart() 获取虚部

    SetRealPart(double d) 设置实部

    SetImaginaryPart(double d) 设置虚部

    ComplexAdd(ComplexNumber c) 复数相加

    ComplexAdd(double c) 复数相加

    ComplexMinus(ComplexNumber c) 复数相减

    ComplexMinus(double c) 复数相减

    ComplexMulti(ComplexNumber c)  复数相乘

    ComplexMulti(double c)  复数相乘

    toString() 把当前复数对象的实部,虚部组合成a+bi的字符串形式

    产品代码

    暂无,因为还不会做。

    测试代码

    暂无,因为还不会做。

遇到的问题与解决方式

由于个人未完成实验代码的编写,此模块内容暂时空白,待补。


体会

之前看到老师发的实验内容,内心一片茫然,没有一点点防备也没有一点点头绪。书到用时方恨少还真那么一回事。平时照着课本敲了代码,看着都懂。待到做实验,真枪实弹检验平常所学时,看着闪烁的光符,犹豫再三却还是不敢下笔,因为脑子里一片空白。看其他同学的代码,感觉也能看懂,但让自己写还是不可以,只能靠晦涩生硬的记忆默写刚才借鉴的同学代码。但实验报告总不能交上白卷一张吧,虽然我不会写,但我还是尝试注释一下其他同学优秀博客的代码吧。以下是卢肖明同学的代码:

测试代码:

package Test;
import exp1.MyComplex;
import org.junit.Test;
import static org.junit.Assert.*;
public class MyComplexTest {
MyComplex a=new MyComplex(1,2);\\ 创建一个实例a
MyComplex b=new MyComplex(1,-4); \\ 创建一个实例b
MyComplex c=new MyComplex(19,0); \\ 创建一个实例c
MyComplex d=new MyComplex(0,-3); \\ 创建一个实例d
MyComplex e=new MyComplex(0,0); \\ 创建一个实例e
@Test
public void getRealPart() throws Exception {
assertEquals(1, MyComplex.getRealPart(1));\\ 输入实部数字1,检验得到实部数字是否为1
assertEquals(-1, MyComplex.getRealPart(-1));\\ 输入实部数字-1,检验得到实部数字是否为-1
assertEquals(5, MyComplex.getRealPart(5)); \\ 输入实部数字5,检验得到实部数字是否为5
assertEquals(22, MyComplex.getRealPart(22));\\ 输入实部数字22,检验得到实部数字是否为22
assertEquals(-100, MyComplex.getRealPart(-100));\\ 输入实部数字-100,检验得到实部数字是否为-100
assertEquals(0, MyComplex.getRealPart(0));\\ 输入实部数字0,检验得到实部数字是否为0
}
@Test
public void getImaginePart() throws Exception {
assertEquals(1, MyComplex.getImaginePart(1));\\ 输入虚部数字1,检验得到虚部数字是否为1
assertEquals(-1, MyComplex.getImaginePart(-1));\\ 输入虚部数字-1,检验得到虚部数字是否为-1
assertEquals(5, MyComplex.getImaginePart(5));\\ 输入虚部数字5,检验得到虚部数字是否为5
assertEquals(22, MyComplex.getImaginePart(22));\\ 输入虚部数字22,检验得到虚部数字是否为22
assertEquals(-100, MyComplex.getImaginePart(-100));\\ 输入虚部数字-100,检验得到虚部数字是否为-1
assertEquals(0, MyComplex.getImaginePart(0));\\ 输入虚部数字0,检验得到虚部数字是否为0
}
@Test
public void add() throws Exception {
assertEquals("(2.0-2.0i)", a.add(b).toString());\\计算复数a加b,并检验
assertEquals("(20.0+2.0i)", a.add(c).toString());\\ 计算复数a加c,并检验
assertEquals("(1.0-1.0i)", a.add(d).toString());\\ 计算复数a加d,并检验
assertEquals("(1.0+2.0i)", a.add(e).toString());\\ 计算复数a加e,并检验
}
@Test
public void minus() throws Exception {
assertEquals("(0.0+6.0i)", a.minus(b).toString());\\ 计算复数a减b,并检验
assertEquals("(-18.0+2.0i)", a.minus(c).toString());\\ 计算复数a减b,并检验
assertEquals("(1.0+5.0i)", a.minus(d).toString());\\ 计算复数a减b,并检验
assertEquals("(1.0+2.0i)", a.minus(e).toString());\\ 计算复数a减b,并检验
}
@Test
public void multiply() throws Exception {
assertEquals("(9.0-2.0i)", a.multiply(b).toString());\\ 计算复数a乘b,并检验
assertEquals("(19.0+38.0i)", a.multiply(c).toString());\\ 计算复数a乘c,并检验
assertEquals("(6.0-3.0i)", a.multiply(d).toString());\\ 计算复数a乘d,并检验
assertEquals("(0.0)", a.multiply(e).toString());\\ 计算复数a乘e,并检验
}
}

产品代码:

package exp1;
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
r = RealPart;
return r;
}
public static int getImaginePart(int ImaginePart){ \\ 输入虚部i
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);\\ 复数乘法细节,i的平方为-1
}
public String toString() {
String rtr_str = "";
if (n > 0)
rtr_str = "(" + m + "+" + n + "i" + ")";
if (n == 0)
rtr_str = "(" + m + ")";
if (n < 0)
rtr_str = "(" + m + n + "i" + ")";
return rtr_str;
}
}

PSP(Personal Software Process)时间

步骤 耗时 百分比
需求分析
设计
代码实现
测试
分析总结

参考资料

*Java学习笔记(第8版)

*《Java学习笔记(第8版)》学习指导

[高其同学博客](http://www.cnblogs.com/20145221GQ/p/5401463.html)

卢肖明同学博客

20145213《Java程序设计》实验二Java面向对象程序设计实验报告的更多相关文章

  1. 20155202 《Java程序设计》实验二(面向对象程序设计)实验报告

    20155202 <Java程序设计>实验二(面向对象程序设计)实验报告 代码托管 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉 ...

  2. 20155239《Java程序设计》实验二(面向对象程序设计)实验报告

    实验内容 初步掌握单元测试和TDD 2.理解并掌握面向对象三要素:封装.继承.多态 3.初步掌握UML建模 4.熟悉S.O.L.I.D原则 5.了解设计模式 实验步骤 单元测试 1.三种代码: 伪代码 ...

  3. 实验二 Java面向对象程序设计

    实验二 Java面向对象程序设计 实验内容 1. 初步掌握单元测试和TDD 2. 理解并掌握面向对象三要素:封装.继承.多态 3. 初步掌握UML建模 4. 熟悉S.O.L.I.D原则 5. 了解设计 ...

  4. 20145206《Java程序设计》实验二Java面向对象程序设计实验报告

    20145206<Java程序设计>实验二Java面向对象程序设计实验报告 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O. ...

  5. 20145308刘昊阳 《Java程序设计》实验二 Java面向对象程序设计 实验报告

    20145308刘昊阳 <Java程序设计>实验二 Java面向对象程序设计 实验报告 实验名称 Java面向对象程序设计 实验内容 初步掌握单元测试和TDD 理解并掌握面相对象三要素:封 ...

  6. 20145113 实验二 Java面向对象程序设计

    20145113 实验二 Java面向对象程序设计 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L.I.D原则 了解设计模式 1.初 ...

  7. JAVA课程实验报告 实验二 Java面向对象程序设计

    北京电子科技学院(BESTI) 实     验    报     告 课程:Java程序设计  班级:1353  姓名:韩玉琪  学号:20135317 成绩:             指导教师:娄嘉 ...

  8. 20145225唐振远 实验二 "Java面向对象程序设计"

    20145225<Java程序设计> 实验二 Java面向对象程序设计 实验报告 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S ...

  9. 20145208 实验二 Java面向对象程序设计

    20145208 实验二 Java面向对象程序设计 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L.I.D原则 了解设计模式 实验步 ...

随机推荐

  1. Reading Famous blog to prevent me wasting time on blind wandering

    I can`t help surfing the useless bbs and some other kind of SNS. The time I begin to do it, it costs ...

  2. IIS 您要访问的网页有问题,无法显示!

    提示:您要访问的网页有问题,无法显示.HTTP 500 – 内部服务器错误.”的问题解决方案! IIS服务器出现错误的原因很多,请尝试以下操作:1.查看网站属性——文档看看启用默认文档中是否存在:in ...

  3. Linux统计文件行数

    语法:wc [选项] 文件… 说明:该命令统计给定文件中的字节数.字数.行数.如果没有给出文件名,则从标准输入读取.wc同时也给出所有指定文件的总统计数.字是由空格字符区分开的最大字符串. 该命令各选 ...

  4. PHP基础 之 基本数据类型练习

    <h3>PHP基础练习</h3> <?php echo "<h4>常量</h4>"; //定义:一般大写,使用下划线间隔 de ...

  5. cocos布局分析

    HBox和VBox布局 HBox只是一个水平布局包装类. HBox里面所有的孩子节点都会水平排列成一行 VBox仅仅是对垂直布局的一个简便的类封装. VBox把它的子节点布局在一竖列中. Layout ...

  6. InnoDB锁机制分析

    InnoDB锁机制常常困扰大家,不同的条件下往往表现出不同的锁竞争,在实际工作中经常要分析各种锁超时.死锁的问题.本文通过不同条件下的实验,利用InnoDB系统给出的各种信息,分析了锁的工作机制.通过 ...

  7. Reflow(渲染)和Repaint(重绘)

    Reflow(渲染):对于DOM结构中的各个元素都有自己的盒模型,浏览器根据各种样式(浏览器的.开发人员定义的等)来计算,并根据计算结果将元素放到它该出现的位置,这个过程称之为reflow. refl ...

  8. C++ 模板函数与模板类

    一.模板函数 函数模板提供了一类函数的抽象,即代表了一类函数.当函数模板被实例化后,它会生成具体的模板函数.例如下面便是一个函数模板:

  9. 如何将代码托管到GitHub上

    注册账号什么的直接省略吧...GitHub传送门:https://github.com/ 首先就是创建repository. 接着就是填写相关的信息了 点击Create repository,创建成功 ...

  10. livezilla账号或密码修改方法

    livezilla的账号和密码不在数据库,保存在php文件里面. 今天想修改一下网站livezilla系统管理员账号和密码,去数据库找了半天没找到,推测可能是存在文件中.搜索了一下,果然是在livez ...