任务:或在公司,该公司将其分为三类人员:部门经理、销售员。在发工资的时候,部门经理拿固定月薪8000元。技术人员按每小时100元领取月薪。销售人员依照500元底薪加当月销售额的4%进行提成。设计并实现一个工资结算系统。

分析:无论是部门经理、技术员还是销售员都具有员工的共同特征。能够先设计一个员工类(Employee)。并将结算工资的方法设计为抽象方法,由于不同的员工有不同的结算工资的方式,须要进行多态实现。所谓的抽象方法就是没有方法体并被abstract修饰符修饰的方法。假设一个类中有抽象方法,这个类就要被声明为抽象类。抽象类不能实例化,也就是说不能创建抽象类的对象。接下来能够在员工类的基础上派生出经理类(Manager)、技术员类(Technician)和销售员类(Salesman),这三个类要对员工类中的抽象方法进行重写(override),给出自己的结算工资的方法的实现,这个过程称为继承(inheritance),这是面向对象程序设计的三大支柱之中的一个。接下来,在须要进行工资结算时。能够将全部的员工对象都赋值给Employee类型的引用(由于无论是部门经理、技术员还是销售员都是员工,父类型的引用能够引用子类型的对象,这是上转型不须要强制的类型转换)。再用相同的引用调用相同的结算工资的方法。这样相同的引用调用相同的方法却做了不同的事(每种员工结算工资的方式全然不一样),这就是面向对象最精髓的东西——多态(polymorphism),它和封装(encapsulation)、继承一起构成了面向对象的三大支柱。

以下是该系统的UML类图。

UML(Unified Modeling Language)称为统一建模语言,。UML是一种开放的方法,用于说明、可视化、构建和编写一个正在开发的、面向对象的、软件密集系统的制品的开发方法。UML展现了一系列最佳project实践,这些最佳实践在对大规模。复杂系统进行建模方面,特别是在软件架构层次已经被验证有效。

简单的说,UML是一种图形化的语言,提供了绘制软件project图纸的标准符号。

上面的图是UML中的类图,它描写叙述了系统中的类以及类与类之间的关系,当中空心的三角型箭头表示继承关系。类与类之间的关系除了继承(IS-A关系)外,还有关联(HAS-A关系)和依赖(USE-A关系)。

该系统的代码例如以下所看到的:

Employee.java

package com.lovo.salsys;

/**
* 员工类
* @author 骆昊
*/
public abstract class Employee {
private String name; // 姓名 /**
* 构造器
* @param name 员工姓名
*/
public Employee(String name) {
this.name = name;
} /**
* 结算工资
* @return 当月月薪
*/
public abstract double getSalary(); /**
* 获得员工姓名
* @return 姓名
*/
public String getName() {
return name;
} @Override
public String toString() {
return name;
}
}

Manager.java

package com.lovo.salsys;

/**
* 部门经理类
* @author 骆昊
*/
public class Manager extends Employee { public Manager(String name) {
super(name);
} public double getSalary() {
return 8000.0;
} public String toString() {
return "[部门经理]" + super.toString();
}
}

Technician.java

package com.lovo.salsys;

/**
* 技术工类
* @author 骆昊
*/
public class Technician extends Employee {
private int workingHour; // 工作时间 public Technician(String name) {
super(name);
} public void setWorkingHour(int workingHour) {
this.workingHour = workingHour;
} public double getSalary() {
return 100 * workingHour;
} public String toString() {
return "[技 术 工]" + super.toString();
}
}

Salesman.java

package com.lovo.salsys;

/**
* 销售员类
* @author 骆昊
*/
public class Salesman extends Employee {
private double sales; // 销售额 public Salesman(String name) {
super(name);
} public void setSales(double sales) {
this.sales = sales;
} public double getSalary() {
return 500 + sales * 0.04;
} public String toString() {
return "[销 售 员]" + super.toString();
}
}

以下是工资结算系统的执行程序SalarySystemRunner.java

package com.lovo.salsys;

import java.util.Scanner;

class SalarySystemRunner {

	public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String[] names = {"张飞", "关羽", "马超", "黄忠", "赵云"};
Employee[] emps = new Employee[names.length];
for(int i = 0; i < emps.length; i++) {
int empType = (int) (Math.random() * 3);
switch(empType) {
case 0: emps[i] = new Manager(names[i]); break;
case 1: emps[i] = new Technician(names[i]); break;
case 2: emps[i] = new Salesman(names[i]); break;
}
System.out.println(emps[i]);
} for(Employee e : emps) {
if(e instanceof Technician) {
System.out.print("请输入" + e.getName() + "的本月工作时间: ");
((Technician) e).setWorkingHour(sc.nextInt());
}
else if(e instanceof Salesman) {
System.out.print("请输入" + e.getName() + "的本月销售额: ");
((Salesman) e).setSales(sc.nextDouble());
}
System.out.println(e.getName() + "本月工资为: $" + e.getSalary());
}
sc.close();
}
}

在此,我们能够为多态下一个更为高大上的定义。其实。类中的实例方法就是对象能够向外界提供的服务,假设站在服务的角度来理解多态,能够这样解释多态:当A系统訪问B系统提供的服务时,B系统有多种提供服务的方式,可是对A系统来说是透明的。上面样例中,A系统就是工资结算系统的执行程序,B系统就是员工系统,员工系统中的结算工资的方法就是B系统向A系统提供的服务。每种员工结算工资的方式都不同,可是A系统仅仅知道员工有结算工资的方法。并不了解B系统中部门经理、技术工和销售员都对该方法做出了不同的实现版本号(多态实现),因此这些对A系统就是透明的(看不见的)。

实现多态有两个关键点:方法重写(子类在继承过程中重写父类方法)和对象造型(将子类对象赋值给父类引用)。这里事实上涉及到了面向对象程序设计两个很重要的原则。一是依赖倒转原则(Dependency Inversion Principle),二是里氏代换原则(Liskov Substitution Principal)。依赖倒转原则讲的是要面向接口编程,而不要面向实现编程。详细的说就是,当定义方法的參数类型、方法的返回类型、对象的引用类型时,有抽象类型尽可能使用抽象类型。上面的样例中,我们将各种不同类型的员工对象对装在Employee类型的数组中就是将对象的引用类型定义为抽象类型。里氏代换原则讲的是不论什么时候都能够用子类对象替换父类对象。也就是说能使用父类型的地方就一定能使用子类型。这样假设一个方法的參数是父类型对象。传入它的不论什么一个子类型都没有问题。假设子类对父类中的方法给出了不同的实现的版本号。那在用父类型的引用调用该方法时就会表现出多态行为。相同的道理,假设一个方法的返回类型是父类型。则在方法中能够返回该父类型的不论什么一个子类型对象,这种话我们在创建对象的时候能够编写一个工厂方法,从而从创建出不同的子类对象,这就是GoF静态设计模式工厂模式。让我们来解释一下在下一章这种设计通过实例。

版权声明:本文博客原创文章,博客,未经同意,不得转载。

[连载]Java程序设计(04)---任务驱动的方法:工资结算系统的更多相关文章

  1. [连载]Java程序设计(03)---任务驱动方式:寻找高富帅和屌丝

    版权声明:本文为博主原创文章,请在转载时说明出处. https://blog.csdn.net/jackfrued/article/details/26163877 任务:相同在上一家公司.公司还须要 ...

  2. 20165231 2017-2018-2 《Java程序设计》第3周学习总结

    教材学习内容总结 对象(Object):存在的具体实体,具有明确的状态和行为 类(Class):具有相同属性和行为的一组对象的集合,用于组合各个对象所共有操作和属性的一种机制 从类看对象:类定义可以视 ...

  3. 20172319 2018.04.01-04.11 《Java程序设计》第5周学习总结

    20172319 2018.04.01-04.11 <Java程序设计>第5周学习总结 目录 教材学习内容总结 教材学习中的问题和解决过程 代码调试中的问题和解决过程 代码托管 上周考试错 ...

  4. 20172319 2018.04.11-16 《Java程序设计教程》 第6周学习总结

    20172319 2018.04.11-16 <Java程序设计教程>第6周学习总结 目录 教材学习内容总结 教材学习中的问题和解决过程 代码调试中的问题和解决过程 代码托管 上周考试错题 ...

  5. 20172319 2018.04.11 《Java程序设计教程》第7周课堂测验(补写博客)

    20172319 2018.04.11 <Java程序设计教程>第7周课堂测验 课程:<程序设计与数据结构> 班级:1723 学生:唐才铭 学号:20172319 指导老师:王 ...

  6. 20145219 《Java程序设计》第04周学习总结

    20145219 <Java程序设计>第04周学习总结 教材学习内容总结 继承 继承就是避免多个类间重复定义共同行为. 面向对象中,子类继承父类,就是把程序中相同的代码部分提升为父类. R ...

  7. 20145218 《Java程序设计》第04次实验报告

    北京电子科技学院(BESTI)实验报告 课程:Java程序设计 班级:1452 指导教师:娄嘉鹏 实验日期:2016.04.22 实验名称:Android开发基础 一.实验内容 1.基于Android ...

  8. Java/JSP程序连接不上Mysql驱动问题解决方法

    错误提示: java.lang.ClassNotFoundException: com.mysql.jdbc.Driverat java.net.URLClassLoader$1.run(URLCla ...

  9. 20145218 《Java程序设计》第02次实验报告

    北京电子科技学院(BESTI)实验报告 课程:Java程序设计 班级:1452 指导教师:娄嘉鹏 实验日期:2016.04.12 实验名称:Java面向对象程序设计 一.实验内容 初步掌握单元测试和T ...

随机推荐

  1. Dapper的使用

    轻量型ORM框架Dapper的使用 /// <summary> /// 查询操作 /// </summary> /// <typeparam name="T&q ...

  2. C++11的一些功能

    .断言是将一个须要为真的表达式放在语句中,在debug模式下检查一些逻辑错误的參数.C++中使用assert须要使用<assert.h>或者<cassert>头文件.有函数定义 ...

  3. JQuery EasyUI学习框架

    前言 前端技术,新项目的开发拟使用EasyUI框架(基于EasyUI丰富UI组件库),项目负责人的提示EasyUI分配给我这个任务.发展前,我需要这对于一个新手EasyUI框架学习一些基本的入门.记录 ...

  4. 刷牙LeetCode思考

    时间已经到了不自觉地,3在五月中旬.今天正式LeetCode自由181刷牙的问题.感觉,以提高他们的算法非常有帮助. 第一个主要的深搜索,广泛搜索,DP他已经掌握7788.也有自己写的代码格公式,使用 ...

  5. SQL开发中容易忽视的一些小地方(五)

    原文:SQL开发中容易忽视的一些小地方(五) 背景: 索引分类:众所周知,索引分为聚集索引和非聚集索引. 索引优点:加速数据查询. 问题:然而我们真的清楚索引的应用吗?你写的查询语句是否能充分应用上索 ...

  6. SharePoint 2013 禁用搜索服务

    原文:SharePoint 2013 禁用搜索服务 前言,在SharePoint2013中,对于硬件需求的提升,让我们虚机里安装总是一筹莫展,尤其开启了搜索服务以后,对于内存的消耗就更加严重,尤其对于 ...

  7. 一个人ACM(我们赶上了ACM)

    时间过得真快,不经意间我已经花了两年的大学生活,现在是时候写的东西.纪念馆两年左右的时间,最近一直在玩博客.我写了一个博客.纪念我们终将逝去的青春. 就从报考说起吧.高考成绩一般,自己选择了土建类的学 ...

  8. 关于 pthread_cond_wait 和 pthread_cond_signal , signal 无效的问题

    关于一个消费者模式,,,引起的问题.. 我在io线程里不断的把一个函数调用放到队列里 然后ruby线程就不断的从这个队列里取出函数之争并运行. 典型的 消费者模式. 我曾经以为是这样... 这是wor ...

  9. ORA-00838: Specified value of MEMORY_TARGET is too small(转)

    1. 测试环境OS: RHEL5U5(32bit)DB: Oracle 11.2.0.3.0(32bit) 2.   异常原因. 2.1 oracle 11g默认sga_target为0,如下图, O ...

  10. 【Hibernate步步为营】--复合主键映射具体解释

    上篇文章讨论了继承映射,它是对象模型中最主要的特性,对于继承映射它的主要区分是字段类型的不同,所以在生成表结构时须要有新列来标识数据的类型,能够使用<subclass>标签并在标签中加入d ...