Java基础(员工工资管理系统)

article/2025/9/29 17:43:18

项目介绍:

某公司的雇员分为以下若⼲类:

SalariedEmployee:拿固定⼯资的员⼯。

HourlyEmployee:按⼩时拿⼯资的员⼯,每⽉⼯作超出160⼩时的部分按照1.5倍⼯资发放 

SalesEmployee:销售⼈员,⼯资由⽉销售额和提成率决定。3万以下,提成率5%,3万以上提成率8% 

BasePlusSalesEmployee:有固定底薪的销售⼈员,⼯资由底薪加上销售提成部分。 提成率5%

所有员工如果该⽉员⼯过⽣⽇,则公司会额外奖励100元。

注意:要求把每个类都做成完全封装,不允许⾮私有化属性。

项目分析

  1. 每个员工都有姓名,薪资,生日月份的属性,因此可以设计以下类
  2. 设计一个所有员工的总父类Employee,具有姓名,生日的属性,具有根据生日月份确定工资一个方法

  3. SalariedEmployee 是Employee的子类 ,拿固定工资,拥有独立的属性月薪

  4. HourlyEmployee是Employee的子类, 独立的属性:每小时的工资数,每月工作的小时数 

  5. SalesEmployee 是Employee的子类 独立的属性:销售额

  6. BasePlusSalesEmployee 是SalesEmployee的子类:独立的属性: 底薪

知识了解

Java抽象(abstract)类

在 Java 中抽象类的语法格式如下:

<abstract>class<class_name> {<abstract><type><method_name>(parameter-iist);
}
其中,abstract 表示该类或该方法是抽象的;class_name 表示抽象类的名称;method_name 表示抽象方法名称,parameter-list 表示方法参数列表。

如果一个方法使用 abstract 来修饰,则说明该方法是抽象方法,抽象方法只有声明没有实现。需要注意的是 abstract 关键字只能用于普通方法,不能用于 static 方法或者构造方法中。

抽象方法的 3 个特征如下:
  1. 抽象方法没有方法体
  2. 抽象方法必须存在于抽象类中
  3. 子类重写父类时,必须重写父类所有的抽象方法

注意:在使用 abstract 关键字修饰抽象方法时不能使用 private 修饰,因为抽象方法必须被子类重写,而如果使用了 private 声明,则子类是无法重写的。

抽象类的定义和使用规则如下:
  1. 抽象类和抽象方法都要使用 abstract 关键字声明。
  2. 如果一个方法被声明为抽象的,那么这个类也必须声明为抽象的。而一个抽象类中,可以有 0~n 个抽象方法,以及 0~n 个具体方法。
  3. 抽象类不能实例化,也就是不能使用 new 关键字创建对象。

Calendar的使用

一、 如何创建 Calendar 对象

Calendar 是一个抽象类, 无法通过直接实例化得到对象。因此, Calendar 提供了一个方法 getInstance,来获得一个Calendar对象, 得到的 Calendar 由当前时间初始化。

 Calendar cal = Calendar.getInstance();

二、 字段解释

Calendar 中 set 和 get 时间都是通过在参数中填入不同的字段来实现的, 不过有部分字段的常量值与约定俗成的值不相同。

下面字段我们以 1997 年 11 月 09 日 00 时 13分 11 秒 来讲解

 Calendar cal = Calendar.getInstance();cal.set(Calendar.YEAR, 1997);cal.set(Calendar.MONTH, 11);cal.set(Calendar.DATE, 09);cal.set(Calendar.HOUR_OF_DAY, 00);cal.set(Calendar.MINUTE, 13);cal.set(Calendar.SECOND, 11);
  • YEAR:默认情况下指示为当前年份。
  • MONTH:指示当前年中的月份数,一年中的一月的值为 0
  • 需要注意的是 JANUARY, FEBRUARY, MARCH,,APRIL,MAY,JUNE,JULY,AUGUST,SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER 分别与 [0, 11] 对应,在设置和获取日期时要格外注意。
  • WEEK_OF_YEAR:指示当前年中的星期数。 一年中的第一个星期的值为 1。
  • WEEK_OF_MONTH:指示当前月中的星期数。 一个月中第一个星期的值为 1。
  • DAY_OF_MONTH:指示一个月中的某天。它与 DATE 是同义词. 一个月中第一天的值为 1。
  • DATE:同 DAY_OF_MONTH
  • DAY_OF_YEAR:指示当前年中的天数。 一年中第一天的值为 1。
  • DAY_OF_WEEK:指示一个星期中的某天。 一周中第一天的值为 1。
  • 需要注意的是, 与中国人的习惯不同, 此处一周中的第一天为 周日。 一周的顺序依次为: 周日(1),周一(2), 周二(3), 周三(4), 周四(5),周五(6), 周六(7) 在设置和获取日期时要格外注意。
  • AM_PM:指示 HOUR 是在中午之前还是在中午之后。[0, 12) 为上午, AM_PM 值为 1 [12, 24)为下午,AM_PM 值为 0。
  • HOUR:指示上午或下午的小时。
  • 例子中 HOUR 为 11
  • HOUR_OF_DAY:指示一天中的小时。 HOUR_OF_DAY 用于 24 小时制时钟。
  • 例子中 HOUR_OF_DAY 为 23
  • MINUTE:指示一小时中的分钟
  • 例子中 MINUTE 为 11
  • SECOND:指示一分钟中的秒
  • 例子中 SECOND 为 11
     

源码 :

 Employee.java

package overproject;import java.util.Calendar;//销售父类为抽象类,不同的子类定义不同的计算工资方法
public abstract class Employee {private String name;//姓名private int month;//生日月份//构造方法public Employee(String name,int month) {this.name=name;this.month=month;}//姓名和生日月份的get set方法public void setName(String name) {this.name = name;}public String getName() {return name;}public void setMonth(int month) {this.month = month;}public int getMonth() {return month;}//计算工资方法//使用抽象方法//抽象方法只有声明没有实现。需要注意的是 abstract 关键字只能用于普通方法,不能用于 static 方法或者构造方法中。public abstract double getSalary();//判断是否为生日月份,获取额外工资public double getSalarybyBrith(){Calendar calendar= Calendar.getInstance();int mm=calendar.get(Calendar.MONTH)+1;//默认0-11if(month==mm){return 100;}elsereturn 0;}}

SalariedEmployee.java

package overproject;//拿固定⼯资的员⼯类
public class SalariedEmployee extends Employee{private double monthSalary;//固定月薪月薪//set get方法public double getMonthSalary() {return monthSalary;}public void setMonthSalary(double monthSalary) {this.monthSalary = monthSalary;}//构造方法public SalariedEmployee(String name, int month, double monthSalary) {super(name, month);//调用父类构造方法this.monthSalary = monthSalary;}//计算工资方法@Overridepublic double getSalary() {//当月薪资加是否为生日月份return this.monthSalary+this.getSalarybyBrith();}
}

HourlyEmployee.java

package overproject;//小时工
public class HourlyEmployee extends Employee{private double timesalaries;//每小时工资private int timemonth;//每月工作小时数//构造函数public HourlyEmployee(String name, int month, double timesalaries,int timemonth) {super(name, month);this.timesalaries = timesalaries;this.timemonth = timemonth;}//set get方法public double getTimesalaries() {return timesalaries;}public void setTimesalaries(double timesalaries) {this.timesalaries = timesalaries;}public double getTimemonth() {return timemonth;}public void setTimemonth(int timemonth) {this.timemonth = timemonth;}//计算工资方法//每⽉⼯作超出160⼩时的部分按照1.5倍⼯资发放@Overridepublic double getSalary() {if(this.timemonth<160&&this.timemonth>0){return (this.timemonth*this.timesalaries)+this.getSalarybyBrith();}else if(this.timemonth>160){return ((this.timemonth-160)*(this.timesalaries*1.5))+160*this.timesalaries+this.getSalarybyBrith();}elsereturn 0;}
}

SalesEmployee.java

package overproject;//无固定底薪的销售工
//⼯资由⽉销售额和提成率决定。3万以下,提成率5%,3万以上提成率8%
public class SalesEmployee extends Employee{private  double sales;//销售额public SalesEmployee(String name, int month, double sales) {super(name, month);this.sales = sales;}public double getSales() {return this.sales;}public void setSales(double sales) {this.sales = sales;}//计算工资方法@Overridepublic double getSalary() {if(sales<30000&&sales>0){return sales*0.05+this.getSalarybyBrith();}else if(sales>30000){return 30000*0.05+(sales-30000)*0.08+this.getSalarybyBrith();}elsereturn 0;}
}

BasePlusSalesEmployee.java

package overproject;//有固定底薪的销售⼈员,⼯资由底薪加上销售提成部分。 提成率5%public class BasePlusSalesEmployee extends SalesEmployee{private double salarlies;//底薪public BasePlusSalesEmployee(String name, int month, double sales, double salarlies) {super(name, month, sales);this.salarlies = salarlies;}public double getSalarlies() {return salarlies;}public void setSalarlies(double salarlies) {this.salarlies = salarlies;}//计算工资方法@Overridepublic double getSalary(){return this.salarlies+this.getSales()*0.05+this.getSalarybyBrith();}
}

 test.java 

package overproject;
import java.util.Scanner;public class test {public static void main(String[] args) {Scanner sc= new Scanner(System.in);System.out.println("请输入拿固定工资的人数:");int number1=sc.nextInt();//创建一个数组,保存number1个固定工资的人数SalariedEmployee[] salariedemployee=new SalariedEmployee[number1];System.out.println("请输入拿无固定底薪的人数:");int number2=sc.nextInt();SalesEmployee[] salesEmployee=new SalesEmployee[number2];System.out.println("请输入拿有固定底薪的人数:");int number3=sc.nextInt();BasePlusSalesEmployee[] basePlusSalesEmployee=new BasePlusSalesEmployee[number3];System.out.println("请输入打小时工的人数:");int number4=sc.nextInt();HourlyEmployee[] hourlyEmployee=new HourlyEmployee[number4];int type;do {System.out.println("***欢迎使用员工工资管理系统****");System.out.println("**************************");System.out.println("0-退出         1-固定工资员工");System.out.println("2-无固定底薪    3-有固定底薪");System.out.println("4-小时工       5-打印工资表 ");System.out.println("请输入选项:");type=sc.nextInt();switch (type) {case 1:for (int i = 0; i < salariedemployee.length; ++i) {System.out.println("请输入第"+(i+1)+"个员工姓名:");String name = sc.next();System.out.println("请输入第"+(i+1)+"个员工出生月份:");int month = sc.nextInt();System.out.println("请输入第"+(i+1)+"个员工月薪:");double monthSalary = sc.nextDouble();SalariedEmployee salariedemployees = new SalariedEmployee(name, month, monthSalary);salariedemployee[i] = salariedemployees;}break;case 2:for (int i = 0; i < salesEmployee.length; ++i) {System.out.println("请输入第"+(i+1)+"个员工姓名:");String name = sc.next();System.out.println("请输入第"+(i+1)+"个员工出生月份:");int month = sc.nextInt();System.out.println("请输入第"+(i+1)+"个员工销售额:");int sales = sc.nextInt();SalesEmployee salesEmployees = new SalesEmployee(name, month, sales);salesEmployee[i] = salesEmployees;}break;case 3:for (int i = 0; i < basePlusSalesEmployee.length; ++i) {System.out.println("请输入第"+(i+1)+"个员工姓名:");String name = sc.next();System.out.println("请输入第"+(i+1)+"个员工出生月份:");int month = sc.nextInt();System.out.println("请输入第"+(i+1)+"个员工销售额:");int sales = sc.nextInt();System.out.println("请输入第"+(i+1)+"个员工底薪:");int salarlies = sc.nextInt();BasePlusSalesEmployee basePlusSalesEmployees = new BasePlusSalesEmployee(name, month, sales, salarlies);basePlusSalesEmployee[i] = basePlusSalesEmployees;}break;case 4:for (int i = 0; i < hourlyEmployee.length; ++i) {System.out.println("请输入第"+(i+1)+"个员工姓名:");String name = sc.next();System.out.println("请输入第"+(i+1)+"个员工出生月份:");int month = sc.nextInt();System.out.println("请输入第"+(i+1)+"个员工每月工作时长(h):");int timemonth = sc.nextInt();System.out.println("请输入第"+(i+1)+"个员工每小时时薪:");int timesalaries = sc.nextInt();HourlyEmployee hourlyEmployees = new HourlyEmployee(name, month, timesalaries, timemonth);hourlyEmployee[i] = hourlyEmployees;}break;case 5:for (int i = 0; i < salariedemployee.length; ++i) {System.out.println("员工姓名:" + salariedemployee[i].getName() + "\t\t" + "员工薪资:" + salariedemployee[i].getSalary());}for (int i = 0; i < salesEmployee.length; ++i) {System.out.println("员工姓名:" + salesEmployee[i].getName() + "\t\t" + "员工薪资:" + salesEmployee[i].getSalary());}for (int i = 0; i < basePlusSalesEmployee.length; ++i) {System.out.println("员工姓名:" + basePlusSalesEmployee[i].getName() + "\t\t" + "员工薪资:" + basePlusSalesEmployee[i].getSalary());}for (int i = 0; i < hourlyEmployee.length; ++i){System.out.println("员工姓名:" + hourlyEmployee[i].getName() + "\t\t" + "员工薪资:" + hourlyEmployee[i].getSalary());}break;case 0:break;default:System.out.println("您的输入有误!请重新输入");}}while(type!=0);}
}

 最终效果:

 

 

这是一个练手的小项目,适合初学Java,对基本知识的一个复习 

 


http://chatgpt.dhexx.cn/article/YnjbPwMX.shtml

相关文章

2020年5大一线城市Java薪资水平汇总,你还差多少呢?

程序员作为薪资最高的行业之一,一直是很多人转行的热门首选行业。Java程序员又在所有程序员中占比最大, 因此,Java程序员的薪资就能够很好的代表行业的薪资水准。 今天就为大家整理5大热门城市的Java薪资情况,看看你还差多少,你又想拿多少?或者你希望去哪个城市发展呢?…

Redis LRU

一&#xff1a;Redis内存驱逐的几种策略 检测易失数据&#xff08;可能会过期的数据集server.db[i].expires &#xff09; ① volatile-lru&#xff1a;挑选最近最少使用的数据淘汰 ② volatile-lfu&#xff1a;挑选最近使用次数最少的数据淘汰 ③ volatile-ttl&#xff1a…

LRU链表及LRU缓存

注&#xff1a;本文分析基于linux-4.18.0-193.14.2.el8_2内核版本&#xff0c;即CentOS 8.2 1、 关于LRU LRU即Least recently used&#xff0c;也就是最近最少使用&#xff0c;一般用作缓存淘汰上&#xff0c;它的核心思想是——如果一个数据在最近一段时间没有被访问到&…

14.1 LRU链表

在最近几十年操作系统的发展过程中&#xff0c;有很多页面交换算法&#xff0c;其中每个算法都有各自的优点和缺点。linux内核中采用的页面交换算法主要是LRU算法和第二次机会法(second chance)。 LRU链表 LRU是least recently used&#xff08;最近最少使用&#xff09;的缩写…

mysql lru_MySQL · 源码分析 · InnoDB LRU List刷脏改进之路

之前的一篇内核月报MySQL 引擎特性 InnoDB Buffer Pool 中对InnoDB Buffer pool的整体进行了详细的介绍。文章已经提到了LRU List以及刷脏的工作原理。本篇文章着重从MySQL 5.7源码层面对LRU List刷脏的工作原理&#xff0c;以及Percona针对MySQL LRU Flush的一些性能问题所做…

图解LRU算法

目录 一、什么是LRU算法? 二、基于双向链表Map实现LRU算法 1. 用双向链表看成cache缓存, 数据存放在链表上的每个节点上。 2. 用Map记录访问cache的历史, 只要访问了 cache就将节点放置Map里。 3. 图解移动节点和淘汰策略过程 三、完整代码 四、借助LinkedHashMap实现 一…

mysql lru_浅析MySQL的lru链表

一、简述传统的LRU链表 LRU&#xff1a;Least Recently Used 相信大家对LRU链表是不陌生的&#xff0c;它算是一种基础的数据结构吧&#xff0c;而且想必面试时也被问到过什么是LRU链表&#xff0c;甚至是让你手写一个LRU链表。 想必你已经知道了MySQL的Buffer Pool机制以及MyS…

LRU实现算法

转载自&#xff1a;https://www.cnblogs.com/Dhouse/p/8615481.html 四种实现方式 LRU 1.1. 原理 LRU&#xff08;Least recently used&#xff0c;最近最少使用&#xff09;算法根据数据的历史访问记录来进行淘汰数据&#xff0c;其核心思想是“如果数据最近被访问过&#x…

Redis LRU算法

一、配置Redis内存淘汰策略 maxmemory 100mbmaxmemory-policy allkeys-lrumaxmemory-samples 5注意&#xff1a;Redis的LRU算法并非完整的实现&#xff0c;而是近似LRU的算法&#xff0c;详细介绍点击这里 二、LRU实现原理 1、双向链表 哈希表 1、哈希表&#xff1a;查找快&…

LRU链表介绍

文章目录 1. 简介2. LRU 组织 2.1 LRU 链表2.2 LRU Cache2.3 LRU 移动操作 2.3.1 page 加入 LRU2.3.2 其他 LRU 移动操作3. LRU 回收 3.1 LRU 更新3.2 Swappiness3.3 反向映射3.4 代码实现 3.4.1 struct scan_control3.4.2 shrink_node()3.4.3 shrink_list()3.4.4 shrink_acti…

LRU页面回收

内存回收算法总是会在一定的时间将一些内存回收&#xff0c; 内存回收算法是通过LRU链表对page页面进行管理的&#xff0c;对于那些新的页面会将其插入到LRU链表头&#xff0c;回收时将返回LRU链表末尾的元素&#xff0c;代表老化程度最高的页面 基本数据结构 typedef struct…

利用数组实现lru

LRU主要包含两个函数&#xff0c;第一个插入一个页面&#xff0c;第二个获得一个页面 主要思路如下&#xff0c;当插入页面的时候&#xff0c;所有的页面向后移动一个单位&#xff08;若果多出来一个元素舍弃掉&#xff09;&#xff0c;然后把这个页面放到数组首元素 当获得一…

什么是LRU(最近最少使用)算法?

一、什么是LRU&#xff1f; LRU&#xff08;Least Recently Used&#xff09;&#xff0c;最近最少使用。 是一种【内存管理】算法。 LRU算法基于一种假设&#xff1a; 长期不被使用的数据&#xff0c;在未来被用到的几率也不大。因此&#xff0c;当数据所占内存达到一定阈值时…

什么是LRU算法

什么是LRU LRU 英文全称&#xff08;Least recently used&#xff0c;最近最少使用&#xff09;属于典型的内存管理算法。 内存管理的一种页面置换算法&#xff0c;对于在内存中但又不用的数据块&#xff08;内存块&#xff09;叫做LRU&#xff0c;操作系统会根据哪些数据属于…

LRU缓存实现与原理

概念 LRU是 Least Recently Used 的缩写&#xff0c;即最近最少使用页面置换算法&#xff0c;是为虚拟页式存储管理服务的&#xff0c;是根据页面调入内存后的使用情况进行决策了。由于无法预测各页面将来的使用情况&#xff0c;只能利用“最近的过去”作为“最近的将来”的近似…

LRU算法的详细介绍与实现

1.背景 LRU&#xff08;least recently used-最近最少使用算法&#xff09;&#xff0c;是一种内存数据淘汰策略&#xff0c;使用常见是当内存不足时&#xff0c;需要淘汰最近最少使用的数据。LRU常用语缓存系统的淘汰策略。 2.LRU原理 LRU最早实在操作系统接触到这个算法的…

LRU原来如此简单

文章目录 前言一、LRU是什么&#xff1f;二、LFU是什么&#xff1f;三、LRU和LFU的比较四、LFU代码实现&#xff08;看懂LFU就自然懂了LRU了&#xff09;1、LFU类2、Node类3、测试 写在最后&#xff0c;感谢点赞关注收藏转发 前言 现在缓存技术在项目中随处可见&#xff0c;但…

LRU算法详解

概念理解 1.LRU是Least Recently Used的缩写&#xff0c;即最近最少使用页面置换算法&#xff0c;是为虚拟页式存储管理服务的&#xff0c;是根据页面调入内存后的使用情况进行决策了。由于无法预测各页面将来的使用情况&#xff0c;只能利用“最近的过去”作为“最近的将来”的…

LRU算法

1.什么是LRU算法 LRU算法又称最近最少使用算法&#xff0c;它的基本思想是长期不被使用的数据&#xff0c;在未来被用到的几率也不大&#xff0c;所以当新的数据进来时我们可以优先把这些数据替换掉。 在LRU算法中&#xff0c;使用了一种有趣的数据结构&#xff0c;称为哈希链…

巧用 NGINX 实现大规模分布式集群的高可用性

原文作者&#xff1a;陶辉 原文链接&#xff1a;巧用 NGINX 实现大规模分布式集群的高可用性 - NGINX开源社区 转载来源&#xff1a;NGINX开源社区 本文是我对2019年GOPS深圳站演讲的文字整理。这里我希望带给各位读者的是&#xff0c;如何站在整个互联网背景下系统化地理解Ngi…