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

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

时间:2023-06-20 14:02:43浏览次数:39  
标签:Java String 04 --- Employee return 方法 public name


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

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

下面是该系统的UML类图。

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

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

	@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,String,04,---,Employee,return,方法,public,name
From: https://blog.51cto.com/u_16166070/6522213

相关文章

  • 松下PLC编程 FP-XH 10轴定位 松下PLC项目实例,两台CPU间通过
    松下PLC编程FP-XH10轴定位松下PLC项目实例,两台CPU间通过RS485通讯,10轴定位控制。轴控制程序采用FB,直观可靠,可以重复使用,使用时只需要对fb接口赋值即可,内部已经对系统寄存器做好了处理。拥有此fb,编程小白也能像高手一般轻松做伺服控制。整个网络使用RS485,两台PLC和一台触摸屏提......
  • Time Interval Aware Self-Attention for Sequential Recommendation
    目录概符号说明MotivationTiSASRec代码LiJ.,WangY.,McAuleyJ.Timeintervalawareself-attentionforsequentialrecommendation.WSDM,2020.概本文介绍了一种更好利用时间戳信息的方式,引入相对位置编码.符号说明Motivation无论是GRU4Rec,还是SASRec等,......
  • 西门子S7-1200 PLC双轴算法控制程序 西门子PLC做的电池焊接程序,
    西门子S7-1200PLC双轴算法控制程序西门子PLC做的电池焊接程序,电池包里面有n*m行列个电池,主要功能:1.每个电池的焊点坐标能够独立调整2.每个电池的焊接能量可独立选择3.任意一个或者多个电池可以随机选择不焊接4.可以选择某一边电池焊接5.可以灵活选择焊接方式6.可存储5套不同产品......
  • 西门子S7-300整条生产线项目程序资料 西门子S7-300 PLC做的某汽车行业
    西门子S7-300整条生产线项目程序资料西门子S7-300PLC做的某汽车行业的生产线程序。300CPU一套西门子触摸屏TP700两套远程ET200站点ProfibusDP网络系统PLC,HMI,ET200,profibusdp网络压力值模拟量采集位移传感器模拟量采集pwm控制拧紧系统扫码枪上位机双层输送线激光打标机基恩士视......
  • 西门子PLC S7-1200和Labview以太网通讯通讯周期20MS,自己做的软件,通讯子程序在设备运
    西门子PLCS7-1200和Labview以太网通讯通讯周期20MS,自己做的软件,通讯子程序在设备运行了4年多都没出现问题,1200PLC侧只需要建立两个DB块,一个读一个写,其他不需要任何编程延申科普:西门子PLCS7-1200:西门子是一家知名的工业自动化解决方案提供商,PLC(可编程逻辑控制器)是一种用于控制和......
  • Mysql数据导出---select into outfile
    select...intooutfile语法select*fromstudentsorderbyscorelimit100intooutfile'/database/mysql/tmp/students.csv'FIELDSTERMINATEDBY','OPTIONALLYENCLOSEDBY'"'ESCAPEDBY'\'LINEST......
  • fx3u和西门子v20/台达vfd-m/三菱E700 rtu所需硬件:FX3U PLC,FX3U-485BD通信板,变频器。
    fx3u和西门子v20/台达vfd-m/三菱E700rtu所需硬件:FX3UPLC,FX3U-485BD通信板,变频器。功能:使用fx3u-485bd板,rtu通信控制西门子v20/台达VFD-M/三菱E700三种变频器正反转,停止,频率设定,加减速,以及对频率,电压,电流的读取,有运行指示,效果可以看视频,反应及时,运行可靠,三种变频器程序是单个的......
  • 强化学习从基础到进阶-常见问题和面试必知必答[2]:马尔科夫决策、贝尔曼方程、动态规划
    强化学习从基础到进阶-常见问题和面试必知必答[2]:马尔科夫决策、贝尔曼方程、动态规划、策略价值迭代1.马尔科夫决策核心词汇马尔可夫性质(Markovproperty,MP):如果某一个过程未来的状态与过去的状态无关,只由现在的状态决定,那么其具有马尔可夫性质。换句话说,一个状态的下一个状态......
  • 快手数据中台建设 - 大数据服务化之路
    快手数据中台建设-大数据服务化之路 2021-01-0721:58本文是围绕着快手的数据服务化中台进行介绍。第一部分是背景介绍,包括数据开发的痛点,第二部分是介绍大数据服务化平台,包括平台架构以及关键细节详解,第三部分是经验总结和未来思考。( 本文内容已经在2020年Top100全球......
  • v-model、v-bind和v-on三大指令的区别
    v-model在表单输入元素或组件上创建双向绑定。v-model指令用于在表单控件或者组件上创建双向绑定。期望的绑定值类型:根据表单输入元素或组件输出的值而变化  v-bindv-bind指令可以用来绑定标签的属性和样式。要绑定的内容是作为一个JS变量,因此只需要对该内容编写合......