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

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

下面是该系统的UML类图。

UML(Unified Modeling Language)称为统一建模语言,。UML是一种开放的方法,用于说明、可视化、构建和编写一个正在开发的、面向对象的、软件密集系统的制品的开发方法。UML展现了一系列最佳工程实践,这些最佳实践在对大规模,复杂系统进行建模方面,特别是在软件架构层次已经被验证有效。简单的说,UML是一种图形化的语言,提供了绘制软件工程图纸的标准符号。上面的图是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;}@Overridepublic 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程序设计(02)---任务驱动方式:个人所得税计算器

    在上一章,我们开发了一个将英制单位转换成公制单位的程序,如果我们希望该程序更实用一些,实现英制单位(英寸)和公制单位(厘米)的互换,那么代码又该如何编写呢?有一点可以肯定,我们需要在程序中设置决策条件 ...

  2. [连载]Java程序设计(01)---任务驱动方式:英制单位转换成公制单位

    任务:你所在的公司是一家美国的服装设计和制造公司,现在这家公司打算进入欧洲市场,于是需要一个将英制单位(英寸)换算为公制单位(厘米)的程序.已知1英寸=2.54厘米,该程序输入以英寸为单位的长度,显示 ...

  3. 【转】Ubuntu 16.04 Nvidia驱动安装(run方式)

    转自:Ubuntu 16.04 Nvidia驱动安装(run方式)_lihe的博客-CSDN博客 1.下载驱动程序 Nvidia驱动下载 https://www.geforce.cn/drivers/ ...

  4. Linux之Ubuntu20.04安装Java JDK8的两种方式

    Linux之Ubuntu20.04远程安装Java JDK8的两种方式 安装openjdk8 更新软件包列表: sudo apt-get update 安装openjdk-8-jdk: sudo ap ...

  5. Java程序设计任务驱动式教程(第三版)课后习题答案下载

    Java程序设计任务驱动式教程(第三版) 主编:孙修东 王永红 链接:https://pan.baidu.com/s/1TBkycUkp41muj-yGJ5IWIw 提取码:lvi3

  6. 还在用表驱动方式做Go测试?可以试试基准突变测试 | Gopher Daily (2021.10.04) ʕ◔ϖ◔ʔ...

    每日一谚:永远不要在运行时做在编译时间可以做的事情 Go技术生态 还在用表驱动方式做Go测试?可以试试基准突变测试 - https://www.clinicallyawesome.com/2021/1 ...

  7. Java模式设计卖电脑实验报告_20145310《Java程序设计》第2次实验报告

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

  8. java程序设计实训项目_Java程序设计教程与项目实训

    本书以现代教育理念为指导,在讲授方式上注意结合应用开发实例,注重培养学生理解面向对象程序设计思想,以提高分析问题和解决实际问题的能力.采用由浅入深.理论与实践相结合的教学思路,通过大量的实例阐述Jav ...

  9. 2017-2018-2 165X 『Java程序设计』课程 助教总结

    2017-2018-2 165X 『Java程序设计』课程 助教总结 本学期完成的助教工作主要包括: 编写300道左右测试题,用于蓝墨云课下测试: 发布博客三篇:<2017-2018-2 165 ...

  10. 2016-2017-2 《Java程序设计》预备作业1 总结

    2016-2017-2 <Java程序设计>预备作业1 总结 预备作业01:你期望的师生关系是什么见https://edu.cnblogs.com/campus/besti/2016-20 ...

最新文章

  1. 【微信小程序】异步请求,权重,自适应宽度并折行,颜色渐变,绝对定位
  2. 某全球零售客户:上马容器云 驾驭线上业务
  3. 命令行 sc delete 的使用(删除服务项)
  4. tkinter笔记:通过点击button 控制标签的显示 (莫烦python笔记)
  5. 当输入 xxxxHub 后,到网页显示,其间发生了什么?
  6. 国内比较好用的5款测试管理工具
  7. 开源开放 | 开源立体化漏洞情报知识图谱(四维创智)
  8. 人民币读法的java程序_Java浮点数转人民币读法
  9. 2018可能大火的物联网应用
  10. Thrift辅助类,用于简化Thrift编程
  11. 51nod 1106 质数检测
  12. pb 系统托盘实例(定时任务管理)
  13. 关于《web课程设计》网页设计 用html css做一个漂亮的网站 仿新浪微博个人主页
  14. Windows XP 共享 Workgroup无法访问.您可能没有权限使用网络资源
  15. XP系统访问网页无法下载php,window_WinXP因配额不足导致无法访问如何解决,  WindowsXP系统虽然说是已经 - phpStudy...
  16. 雷锋网专访布丁CEO徐磊
  17. 货郎问题java_货郎问题
  18. 使用Nuxt.js框架开发(SSR)服务端渲染项目
  19. iOS音乐播放器小技巧
  20. 全国计算机等级考试准考证编号规则

热门文章

  1. Perl、PHP、Python、Java和Rub之间的异同比较
  2. php实现在线生成条形码示例分享(条形码生成器)
  3. 三次样条插值三弯矩matlab,数值分析课程设计报告书-三次样条插值的三弯矩法...
  4. 文心一言登录成功以后,出现页面空白。
  5. Cocos2d-x 粒子编辑器 Particle Studio 争做 Windows Particle Designer 源代码
  6. Mac下安装redis-rdb-tools工具
  7. 《Java程序员由笨鸟到菜鸟》电子版书正式发布,欢迎大家下载
  8. 查询同一表格中姓名相同但身份证号不同的记录
  9. 戴尔linux改win7教程视频,戴尔笔记本预装win8改win7教程
  10. STM32串口助手小问题