首页 > 技术文章 > JAVA课程实验报告 实验二 JAVA面向对象程序设计

1551127024hwy 2015-05-07 20:17 原文

课程:Java程序设计  班级:1352  姓名:黄伟业  学号:20135315

成绩:             指导教师:娄嘉鹏    实验日期:2015.5.7

实验密级:         预习程度:         实验时间:15:50--20:50

仪器组次:         必修/选修: 选修            实验序号:2

实验目的:

1.掌握单元测试和TDD

2. 理解并掌握面向对象三要素:封装、继承、多态

3. 初步掌握UML建模

4. 熟悉S.O.L.I.D原则

5. 了解设计模式

实验仪器:

名称

型号

数量

PC

Lenovo

1

实验楼环境

/

1

Eclipse

/

1

 一、实验内容及步骤

一、     单元测试和TDD

代码1:

public class MyUtil{

   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 "错误";

   }

}

代码2:

import org.junit.Test;

import junit.framework.TestCase;

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));

    }

}

二、     面向对象三要素

代码1:

public class AnimalTest {

         public static void main(String[]args){

                   Dog d=new Dog();

                   d.setColor("Yellow");

                   getInfo(d);

                  

                   Cat c=new Cat();

                   c.setColor("Black");

                   getInfo(c);

         }

         public static void getInfo(Dog d){

                   System.out.println(d.toString());

         }

         public static void getInfo(Cat c){

                   System.out.println(c.toString());

         }

}

代码2:

package dog;

 

public class DogTest {

         public static void main(String[] args){

                   Dog g=new Dog();

                   g.setColor("Yellow");

                   getInfo();

         }

public static void getInfo(Dog d){

         System.out.println(d.toString());

}

}

代码3:

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

    }

}

三、设计模式实示例

S.O.L.I.D原则

面向对象三要素是“封装、继承、多态”,任何面向对象编程语言都会在语法上支持这三要素。如何借助抽象思维用好三要素特别是多态还是非常困难的,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,依赖倒置原则)

OCP是OOD中最重要的一个原则,OCP的内容是:

software entities (class, modules, function, etc.) should open for extension,but closed for modification.

软件实体(类,模块,函数等)应该对扩充开放,对修改封闭。

基于OCP,利用面向对象中的多态性(Polymorphic),更灵活地处理变更拥抱变化,OCP可以用抽象和继承、面向接口编程手段实现

SRP的内容是:

  • There should never be more than one reason for a class to change
  • 决不要有一个以上的理由修改一个类

LSP的内容是:

  • Subtypes must be substitutable for their base types
  • Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it
  • 子类必须可以被其基类所代
  • 使用指向基类的指针或引用的函数,必须能够在不知道具体派生类对象类型的情况下使用它

ISP的内容是:

  • Clients should not be forced to depend upon interfaces that they do not use
  • 客户不应该依赖他们并未使用的接口

DIP的内容是:

  • High level modules should not depend upon low level modules. Both should depend upon abstractions
  • Abstractions should not depend upon details. Details should depend upon abstractions
  • 高层模块不应该依赖于低层模块。二者都应该依赖于抽象
  • 抽象不应该依赖于细节。细节应该依赖于抽象

注意以下5点:

代码:

abstract class Data {
    abstract public void DisplayValue();
}
class Integer extends  Data {   
    int value;
    Integer() {
         value=100;
    } 
    public void DisplayValue(){
        System.out.println (value);
    }
 }
//20135215
abstract class Factory {
   abstract public Data CreateDataObject();
}
class IntFactory extends Factory {
   public Data CreateDataObject(){
        return new Integer();
   }
}
//20135215
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 IntFactory());
            d.DisplayData();
    }   
}

(四)实验练习

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

代码1:

package complex;

 

public class ComplexTest{

 

    public static void main(String[] args) {

        Complex c=new Complex();

        Complex c1=new Complex(6,12);

        Complex c2=new Complex(11,32);

        c1.Output();

        c2.Output();

        System.out.println("这两复数和为:");

        System.out.println(c.add(c1, c2).r+"+"+c.add(c1, c2).i+"i");

        System.out.println("这两复数差为:");

        System.out.println(c.reduce(c1, c2).r+"+"+c.reduce(c1, c2).i+"i"); 

    }

 

}

代码2:

package complex;

 

public class Complex{

   double r,i;

    Complex()

    {

        this.r=0;//实数

        this.i=0;//复数

    }

    Complex(double re,double im)

    {

        this.r=re;

        this.i=im;

    }

    Complex reduce(Complex p1,Complex p2)

    {

        Complex p =new Complex(p1.r-p2.r,p1.i-p2.i);

        return p;  

    }

    Complex add(Complex p1, Complex p2) {

        Complex p =new Complex(p1.r+p2.r,p1.i+p2.i);

        return p;  

    }

    void Output()

    {

        System.out.println("复数的值为:");

        if(this.i!=0)

        System.out.println(this.r+"+"+this.i+"i");

        else

        System.out.println(this.r);

       

    }

}

实验的好处:

先写出伪代码,可以使在编写产品代码时更加流畅,编写测试代码可以尽量减少产品代码中的bug。因此单元测试可以有效地提高编程效率,减少所写程序中的bug。

实验中遇到的问题:

复数类的定义不了解。

 

二、实验感想

1、这次实验耗费了很长时间,最后都要做不下去了。我深深体会到网络的重要性和学习新方法、使用新工具的能力的重要性。

2、UML图有点抽象,在虚拟机上实现的时候操作不熟练,刚开始一直没明白怎么把那个框调出来(因为实验楼虚拟机一直出问题,自己没有静下心来看操作步骤上“单击工具栏上的类图标,再在class diagram(类图)中单击一下”),之后是那条箭头画不上去,百度教程,应该是先点击工具栏上的箭头图标(实现关系)然后点击起始的类,出现一条虚线,再点击指向的类。终于把能图画出来了。

3、TDD的方式例题的测试代码看得懂,但是自己编写的时候就不知道哪些语句怎么用,只好用自己写的测试代码,可能这样不算严格TDD方式,但是我觉得这样的思想对我自己设计某些独立功能是有很大帮助的。

4、做练习代码的时候,一看到实现复数类不知道具体是要做什么,就上网搜了一下“Complex”,发现有输出、加法、减法的功能,然后我就按着这样的思路编写了伪代码。开始的时候没有把功能抽取出来,啰嗦的写了很多,然后抽取了print功能,将每一项功能单独出来,代码一下就变少了。

然后我写完上述报告后,看到老师给的复数类还有乘法的功能,我就把代码翻出来,再实现了一下乘法的功能:

推荐阅读