课程:Java程序设计 班级:1652班 姓名:王高源 学号:20165225 指导教师:娄嘉鹏 实验日期:2018年4月16日 实验时间:3:35 - 5:15 实验序号:实验二 实验名称:Java面向对象程序设计 实验内容: 1.初步掌握单元测试和TDD 2.理解并掌握面向对象三要素:封装、继承、多态 3.初步掌握UML建模 4.熟悉S.O.L.I.D原则 5.了解设计模式 实验要求: 实现百分制成绩转成“优、良、中、及格、不及格”五级制成绩的功能
TDD步骤:伪代码(思路)→ 测试代码(产品预期功能)→ 产品代码(实现预期功能),这种开发方法叫“测试驱动开发”html
伪代码:伪代码与具体编程语言无关,不要写与具体编程语言语法相关的语句(如用malloc分配内存,这样只能用C语言编程了),伪代码从意图层面来解决问题,最终,伪代码是产品代码最天然的、最好的注释。java
百分制转五分制: 若是成绩小于60,转成“不及格” 若是成绩在60与70之间,转成“及格” 若是成绩在70与80之间,转成“中等” 若是成绩在80与90之间,转成“良好” 若是成绩在90与100之间,转成“优秀” 其余,转成“错误”
可见使用语言简洁明了,随后将伪代码转为产品代码便可。git
public class MyUtil{ public static String percentage2fivegrade(int grade){ //若是成绩小于0,转成“错误” if ((grade < 0)) return "错误"; //若是成绩小于60,转成“不及格” else 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 "优秀"; //若是成绩大于100,转成“错误” else return "错误"; } }
写了产品代码后,咱们还要写测试代码,证实本身的代码没有问题,这样才能将代码放心交到用户手中。编程
public class MyUtilTest { public static void main(String[] args) { // 百分制成绩是50时应该返回五级制的“不及格” if(MyUtil.percentage2fivegrade(50) != "不及格") System.out.println("test failed!"); else System.out.println("test passed!"); } }
成功了。设计模式
不过只测一组就是有偷懒嫌疑了,如今咱们把通常状况都试一下:网络
也成功了app
再看看异常状况下的测试:编程语言
public class MyUtil{ public static String percentage2fivegrade(int grade){ //若是成绩小于0,转成“错误” if ((grade < 0)) return "错误"; //若是成绩小于60,转成“不及格” else 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 "优秀"; //若是成绩大于100,转成“错误” else return "错误"; } }
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!"); } }
public class MyUtil{ public static String percentage2fivegrade(int grade){ //若是成绩小于0,转成“错误” if ((grade < 0)) return "错误"; //若是成绩小于60,转成“不及格” else 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 "优秀"; //若是成绩大于100,转成“错误” else return "错误"; } }
成功了。ide
值得一提的是,Java中有单元测试工具JUnit来辅助进行TDD。模块化
按照老师给的步骤来走不当心就出现下图,觉得是网络问题,结果换了网也没有用:
气死了,再下一次,发现他又好了...
回到原题。
从网上下了一个everything用于查找junit.jar。
而后用老师给的新方法去测试了一下以前的代码:
成功了,而后多是版本问题,个人小绿条变成了小绿勾。
其实以前按照攻略来是失败了的,不过还好有好看的助教学姐指点了我一下,才顺利完成测试。
面向对象(Object-Oriented)的三要素包括:封装、继承、多态。面向对象的思想涉及到软件开发的各个方面,如面向对象分析(OOA)、面向对象设计(OOD)、面向对象编程实现(OOP)。OOA根据抽象关键的问题域来分解系统,关注是什么(what)。OOD是一种提供符号设计系统的面向对象的实现过程,用很是接近问题域术语的方法把系统构形成“现实世界”的对象,关注怎么作(how),经过模型来实现功能规范。OOP则在设计的基础上用编程语言(如Java)编码。贯穿OOA、OOD和OOP的主线正是抽象。
抽象:即“求同存异、去粗取精”的过程。将若干事物中相同的部分进行剥离整理,并造成具备某特定功能的产品,这一过程即为抽象。过程抽象的结果是函数,数据抽象的结果是抽象数据类型其显而易见的好处是(在程序设计中)减小了代码大重复性,提升了效率。
封装:将与某一将数据与相关行为包装在一块儿以实现信息就隐藏,核心内容是模块化和信息隐藏,与此相伴的是接口的使用。
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() + "!"; } }
public class DogTest { public static void main(String[] args) { Dog d = new Dog(); d.setColor("Yellow"); getInfo(d); } public static void getInfo(Dog d) { System.out.println(d.toString()); } }
public class StringBufferDemo { public static void main(String [] args) { StringBuffer buffer = new StringBuffer(); buffer.append('S'); buffer.append("tringBuffer"); System.out.println(buffer.charAt(i)); System.out.println(buffer.capacity()); System.out.println(buffer.length()); System.out.println(buffer.indexOf("tring")); System.out.println("buffer = " + buffer.toString()); } }
然而老师说这个代码不能够直接用,在我把第七行的括号加上后,便完美运行了。
在老师给出的使用JUnit学习Java中,有四个须要咱们去测试的东西:charAt()、capacity()、length()和indexOf。
import junit.framework.TestCase; import org.junit.Test; public class StringBufferDemoTest extends TestCase { StringBuffer a = new StringBuffer("StringBuffer"); StringBuffer b = new StringBuffer("StringBufferStringBuffer"); StringBuffer c = new StringBuffer("StringBufferStringBufferStringBuffer"); @Test public void testcharAt() { assertEquals('S',a.charAt(0)); assertEquals('e',b.charAt(10)); assertEquals('f',c.charAt(20));; } @Test public void testcapacity() { assertEquals(28,a.capacity()); assertEquals(40,b.capacity()); assertEquals(52,c.capacity()); } @Test public void testindexOf() { assertEquals(0,a.indexOf("Str")); assertEquals(3,b.indexOf("ing")); assertEquals(10,c.indexOf("er")); } @Test public void testlength() { assertEquals(12,a.length()); assertEquals(24,b.length()); assertEquals(48,c.length()); } }
SRP(Single Responsibility Principle,单一职责原则)
对象提供单一职责的高度封装,对象的改变仅仅依赖于单一职责的改变
OCP(Open-Closed Principle,开放-封闭原则)
即对扩充开放(功能可增长),对修改封闭(源代码不可改动)
OCP实现手段:(1)抽象和继承,(2)面向接口编程
LSP(Liskov Substitusion Principle,Liskov替换原则)
子类必须能够被其基类所代,父类型对象能够被子类型对象所取代
ISP(Interface Segregation Principle,接口分离原则)
客户不该该依赖他们并未使用的接口
DIP(Dependency Inversion Principle,依赖倒置原则)
示例以下(本身学号%6取余):
abstract class Data { abstract public void DisplayValue(); } class Integer extends Data { int value; Integer() { value=100; } public void DisplayValue(){ System.out.println (value); } } class Short extends Data { short value; Short() { value = 5225; } public void DisplayValue(){ System.out.println (value); } } abstract class Factory { abstract public Data CreateDataObject(); } class IntFactory extends Factory { public Data CreateDataObject(){ return new Integer(); } } class ShortFactory extends Factory { public Data CreateDataObject(){ return new Short(); } } class Document { Data pd; Document(Factory pf){ pd = pf.CreateDataObject(); } public void DisplayData(){ pd.DisplayValue(); } } public class MyDoc { static Document d; public static void main(String[] args) { d = new Document(new ShortFactory()); d.DisplayData(); } }
class ??? extends Data { short value; Short() { value = 5225; } public void DisplayValue(){ System.out.println (value); } } class ???Factory extends Factory { public Data CreateDataObject(){ return new ???(); } } public class MyDoc { static Document d; public static void main(String[] args) { d = new Document(new ???Factory()); d.DisplayData(); } }
Complex类要输出实部,输出虚部,并按照a+bi的形式输出复数。 Complex类中有两个变量,实部RealPart和虚部ImaginePart;, double RealPart;复数的实部 double ImagePart;复数的虚部 getRealPart():返回复数的实部 getImagePart();返回复数的虚部 setRealPart():设置复数的实部 setImagePart();设置复数的虚部 输出形式:a+bi (2)方法: // 定义构造函数 public Complex() public Complex(double R,double I) // 定义公有方法:加减乘除 Complex ComplexAdd(Complex a) 加 Complex ComplexSub(Complex a) 减 Complex ComplexMulti(Complex a) 乘 Complex ComplexDiv(Complex a) 除 //Override Object public boolean equals(Object obj) public String toString():将复数输出成a+bi的格式。
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 = RealPart; return r; } public static int getImaginePart(int ImaginePart){ 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); } public String toString() { String s = ""; if (n > 0) s = "(" + m + "+" + n + "i" + ")"; if (n == 0) s = "(" + m + ")"; if (n < 0) s = "(" + m + n + "i" + ")"; return s; } }
import org.junit.Test; import static org.junit.Assert.*; public class MyComplexTest { MyComplex a=new MyComplex(1,2); MyComplex b=new MyComplex(1,-4); MyComplex c=new MyComplex(19,0); MyComplex d=new MyComplex(0,-3); MyComplex e=new MyComplex(0,0); @Test public void getRealPart() throws Exception { assertEquals(1, MyComplex.getRealPart(1)); assertEquals(-1, MyComplex.getRealPart(-1)); assertEquals(5, MyComplex.getRealPart(5)); assertEquals(22, MyComplex.getRealPart(22)); assertEquals(-100, MyComplex.getRealPart(-100)); assertEquals(0, MyComplex.getRealPart(0)); } @Test public void getImaginePart() throws Exception { assertEquals(1, MyComplex.getImaginePart(1)); assertEquals(-1, MyComplex.getImaginePart(-1)); assertEquals(5, MyComplex.getImaginePart(5)); assertEquals(22, MyComplex.getImaginePart(22)); assertEquals(-100, MyComplex.getImaginePart(-100)); assertEquals(0, MyComplex.getImaginePart(0)); } @Test public void add() throws Exception { assertEquals("(2.0-2.0i)", a.add(b).toString()); assertEquals("(20.0+2.0i)", a.add(c).toString()); assertEquals("(1.0-1.0i)", a.add(d).toString()); assertEquals("(1.0+2.0i)", a.add(e).toString()); } @Test public void minus() throws Exception { assertEquals("(0.0+6.0i)", a.minus(b).toString()); assertEquals("(-18.0+2.0i)", a.minus(c).toString()); assertEquals("(1.0+5.0i)", a.minus(d).toString()); assertEquals("(1.0+2.0i)", a.minus(e).toString()); } @Test public void multiply() throws Exception { assertEquals("(9.0-2.0i)", a.multiply(b).toString()); assertEquals("(19.0+38.0i)", a.multiply(c).toString()); assertEquals("(6.0-3.0i)", a.multiply(d).toString()); assertEquals("(0.0)", a.multiply(e).toString()); } }
说实话,此次实验要我编程我是不会编的..可是还好老师给了模板,只须要改一下就行了。
在实验有了代码支撑后,比较累的地方就是要看好多好多长博客,还有以上提到的一些软件的操做方法你都要学(虽然老师有给出UML的另外一个建模方法,可是我仍是用了别的)。
值得一提的是,此次学到的东西能让我更轻松的去修正代码bug,减小了以后修复所须要的大量精力。
可是无论怎么说,过程仍是很累的,有时候都想把博客所有关掉,好好睡一下,好在最后我写完了。
仍是要继续加油呀!
码云连接(这也是我第一次规范书写git传代码哦)