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. Shader 之 顶点变形

    可以使3D物体通过顶点变形弯曲,常见于跑酷游戏的跑道.可向左.右.上.下弯曲. Shader "Custom/VertexColorCurved" { Properties { / ...

  2. 必须知道的.net——学习笔记1

    1.对象的生成(出生) Person aperson=new Person("小张",25) 构造过程:分配存储空间—初始化附加成员—调用构造函数 2.对象的旅程(在一定的约定与规 ...

  3. phpcms中常用代码总结

    1.调用数据库模型 $this->db = pc_base::load_model('test_model');//从"phpcms/model/"目录下加载模型类文件 其中 ...

  4. 淘宝(阿里百川)手机客户端开发日记第一篇 android 主框架搭建(一)

    android 主框架搭建(一) 1.开发环境:Android Studio 相继点击下一步,直接项目建立完毕(如下图) 图片看的效果如果很小,请放大您的浏览器显示百分比  转载请注明http://w ...

  5. JavaScript判断图片是否加载完成的三种方式

    JavaScript判断图片是否加载完成的三种方式 有时需要获取图片的尺寸,这需要在图片加载完成以后才可以.有三种方式实现,下面一一介绍. 一.load事件 1 2 3 4 5 6 7 8 9 10 ...

  6. BZOJ2466——[中山市选]树

    1.题目大意:给你一棵树,树的每个节点都有一个权值,是0或1,最开始都是0,你可以做一种修改操作,就是把一个节点和它相邻的 节点的权值取反,问最少几次修改能把所有节点的权值变得都是1,最多100个节点 ...

  7. Linux的五个查找命令

    1. find find是最常见和最强大的查找命令,你可以用它找到任何你想找的文件. find的使用格式如下: $ find <指定目录> <指定条件> <指定动作> ...

  8. 这些情况下onReume不应该是你的选择

    面试Android程序员的时候问过以下几个基本问题,得到的回答经常不尽人意: 1, Activity A跳转到Activity B,Activity B完成后,Activity A要刷新一下自己的数据 ...

  9. Linux--多网卡的7种Bond模式

    网卡bond是通过把多张网卡绑定为一个逻辑网卡,实现本地网卡的冗余,带宽扩容和负载均衡.在应用部署中是一种常用的技术,我们公司基本所有的项目相关服务器都做了bond,这里总结整理,以便待查. bond ...

  10. Android SDK在线更新镜像服务器

    http://www.cnblogs.com/tc310/p/4696731.html#_label0