我正在用Java实现一个基本的工资单程序。我有一个名为Employee
的抽象超类,它主要存储税号,名称等数据。然后,我有2个Employee
子类,称为Hourly
和Salaried
代表员工的类型。这两个类实现薪资和税收的计算,并存储特定于其员工类型的数据。
麻烦的是,由于需要实施新的字段来存储计算的工资,税金等,我最终会填满大量的字段。我是否有理由摆脱Salaried
和{{1然后创建一个新的超级类Hourly
,然后让PayCalculation
和PayHourly
类来实现每小时/有薪的特定字段和计算?如果是这样,在PaySalaried
(超类)和Employee
(子类)之间建立组合关系会有意义吗?
我对作文了解不多。如果有人能想出更好的结构方法,我会非常感激。
我不知道如何使用UML,但这是一个非常糟糕的图表,我用油漆来解释这个。
答案 0 :(得分:2)
是的,在Employee
和PayCalculation
之间建立合成关系是有意义的。
以实际的方式思考这个问题,因为 - Employee
将payCalculations
,workingHourCalculations
等作为字段/组合而不是相反。
同样Employee
可以有抽象方法来计算薪酬,工作等。员工的实例字段可以容纳计算薪酬,工作等所需的成员。
Public Employee {
private Map payCalMap;
.....
public double calculatePay();
}
答案 1 :(得分:2)
员工的班级将付款计算委托给PayCalculation界面方法 calculate()。
通过替换此接口的实现,您可以实现不同的行为。
class Employee {
private PayCalculation payCalculation;
public Employee(PayCalculation calculation){
this.calculation = calculation;
}
public void calculatePayment(){
payCalculation.calculate();
}
}
public interface PayCalculation{
public void calculate();
}
class PayHourly implements PayCalculation{
public void calculation(){
System.out.println("Hourly-paid");
}
}
class PaySalaried implements PayCalculation{
public void calculate(){
System.out.println("Salary-paid");
}
}
然后,您使用不同的付款系统创建2个不同的员工:
Employee salaryPaidEmployee = new Employee(new PaySalaried());
Employee hourlyPaidEmployee = new Employee(new PayHourly());
并根据付款系统计算付款:
salaryPaidEmployee.calculatePayment();
hourlyPaidEmployee.calculatePayment();
答案 2 :(得分:1)
Employee
,Salaried(Employee)
和Hourly(Employee)
非常适合作为课程。
PayCalculation()
,PayHourly()
和PaySalaried()
听起来更像是方法,对吗?
所以你可以做的是在超类(Employee)中创建一个抽象方法(意味着你实际上没有实现它)PayCalculation()
。然后,您可以(实际上必须)在您的Salaried和Hourly类中编写PayCalculation()
的实现。
这意味着,当您在Hourly对象上调用PayCalculation()时,它将与在Salaried对象上调用PayCalculation()时完全不同。
这有意义吗?真正深入思考这些概念 - 试图掌握继承的概念,实际上是试图掌握面向对象编程的概念。
如果我能以不同的方式解释,请告诉我 - 不久前,我正在围绕这些相同的概念。
另外,您在上面的评论中是正确的。 Employee和Hourly / Salaried之间没有“有”关系。他们之间存在的关系是“是一种”关系:每小时一名员工是一名员工。这意味着你需要考虑继承,而不是构图 - 这正是我们在这里所讨论的。
这应该是这个问题的结果:你想要掌握的是继承,而不是构成。