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

任务:或在公司,该公司将其分为三类人员:部门经理、销售员。在发工资的时候,部门经理拿固定月薪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静态设计模式工厂模式。让我们来解释一下在下一章这种设计通过实例。

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

时间: 2025-01-03 03:19:40

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

[连载]Java程序设计(04)---任务驱动方式:工资结算系统

任务:还是在上一家公司,该公司将职员分为三类:部门经理.技术员和销售员.在发工资的时候,部门经理拿固定月薪8000元,技术人员按每小时100元领取月薪,销售人员按照500元底薪加当月销售额的4%进行提成,设计并实现一个工资结算系统. 分析:不管是部门经理.技术员还是销售员都具有员工的共同特征,可以先设计一个员工类(Employee),并将结算工资的方法设计为抽象方法,因为不同的员工有不同的结算工资的方式,需要进行多态实现.所谓的抽象方法就是没有方法体并被abstract修饰符修饰的方法.如果一个

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

任务:你所在的公司是一家美国的服装设计和制造公司,现在这家公司打算进入欧洲市场,于是需要一个将英制单位(英寸)换算为公制单位(厘米)的程序.已知1英寸=2.54厘米,该程序输入以英寸为单位的长度,显示该长度对应的厘米数.例如:输入英寸:2.5,输出:2.5英寸=6.35厘米. package com.lovo; import java.util.Scanner; public class MyConverter { public static void main(String[] args) {

[连载]Java程序设计(02)---任务驱动方式:个人所得税计算器

上周有厂商到公司测试,拿了一块据说很猛的网络处理加速PCIe板卡,拎在手里沉甸甸的很有分量,最让人意淫的是那4个万兆光口,于是我迫不及待的想要一览光口转发时那种看不见的震撼.       可是,仅凭4个光口怎么测试?起码你要有个"对端"啊!任何人应该都不想扛着三台机器在客户们之间跑来跑去测试其转发性能,当然你也不能指望客户那里就一定有你需要的"对端"设备,比如我们公司就没有这种和万兆光口对接的设备,不过赶巧的是,那天还真有一台设备带有万兆光口,但是只是碰巧了.最佳的

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

1. Sphin x简介 1.1. 什么是全文检索 全文检索是指以文档的全部文本信息作为检索对象的一种信息检索技术 .检索的对象有可能是文章的标题,也有可能是文章的作者,也有可能是文章摘要或内容. 1.2. 介绍 Sphin x是一个基于SQL的全文检索引擎,可以结合MySQL,PostgreSQL做全文搜索,它可以提供比数据库本身更专业的搜索功能 ,使得应用程序更容易实现专业化的全文检索.Sphin x特别为一些脚本语言设计搜索API接口 ,如PHP ,Python,Perl,Ruby等,同时

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

教材学习内容总结 对象(Object):存在的具体实体,具有明确的状态和行为 类(Class):具有相同属性和行为的一组对象的集合,用于组合各个对象所共有操作和属性的一种机制 从类看对象:类定义可以视为一个具有类似特性与共同行为的对象的模板,可用来产生对象 从对象看类:类的产生,是从少数实例,推广到大量相似实例的抽象化过程(abstraction) 类是对象的设计图,对象是类的实例,生成对象要先定义类. 类成员变量整个类中有效,局部变量仅在方法中有效. 局部变量的名字与成员变量的名字相同时,成员

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

20172319 2018.04.11 <Java程序设计教程>第7周课堂测验 课程:<程序设计与数据结构> 班级:1723 学生:唐才铭 学号:20172319 指导老师:王志强 日期:2018.04.11 必修/选修:必修 目录 测试内容 测试要求 实验步骤 前期准备 需求分析 代码实现及解释 程序运行结果及代码截图 测试过程及遇到的问题 参考资料 测试内容 完成编程项目PP7.4:具体参考<java程序设计教程>(第八版) Compareble接口的实现 测试要求

java连接sql server 2008的问题(jdbc驱动的方法)

这是程序代码,我是按照网上和视频讲解的步骤写的代码:import java.sql.*;public class jdbc {/*** @param args*/public static void main(String[] args) {// TODO Auto-generated method stubConnection ct = null;PreparedStatement ps = null;ResultSet rs = null;try {//第一步,加载驱动Class.forNa

20155335 俞昆 2016-2017-2 《Java程序设计》第九周学习总结

学号 2016-2017-2 <Java程序设计>第九周学习总结 ##JDBC入门 在正式介绍JDBC前,已知JDBC是用来执行SQL的解决方案,开发人员使用JDBC的标准接口,开发人员不需接触底层数据库驱动程序的差异性. 本章,我们需要了解JDBC与API使用和概念,我们先要认识应用程序如何与数据库进行沟通,数据库本身是一种独立运行的应用程旭,程序员撰写的应用程序是利用通信协议对数据库进行指令交换,以进行数据的增加删除以及查找. 通常应用程序会利用一组专门与数据库进行通信协议的链接库,以简化

20155335俞昆《java程序设计》第十周总结

学号 2016-2017-2 <Java程序设计>第十周学习总结 ## 事实上网络编程,我们可以简单的理解为两台计算机相互通讯数据而已,对于程序员而言,掌握一种编程接口并使用一种编程模型相对而言就简单多了,javaSDK提供了一些相对简单的Api来完成12这些工作,Socket就是其中之一,对于java而言,Api的存在和java.net包里面.因此只要导入这个包就可以准备网络编程了. 客户机到服务机的模型就是网络编程的基本模型,简单的说就是引进这两个进程之间的相互通信,其中一个必须提供固定的