[英]Workaround for returning object in abstract class
我正在为学校制定薪资计划,并且有薪资驱动程序,雇员班,每小时班(扩展雇员), Salaried
阶层(扩展雇员)和SalariedPlusCommission
类别(扩展Salaried)。 下面的代码是Employee对象和Employee中的load()
方法(也是每个子类中的load()
方法)。 我必须有一个抽象方法getEarnings()
所以整个Employee类都是抽象的。 我收到一个错误消息:“雇员是抽象的;无法实例化”。 我知道为什么会收到错误,但不知道如何将信息放入我的Employee对象中。
public Employee(String name, String socialSecurityNumber, int month, int week)
{
this.name=name;
this.socialSecurityNumber=socialSecurityNumber;
this.month=month;
this.week=week;
}
public static Employee load()
{
Scanner stdIn = new Scanner (System.in);
System.out.println("Name ==> ");
name=stdIn.nextLine();
System.out.println("Social Security Number ==>");
socialSecurityNumber=stdIn.nextLine();
System.out.println("Birthday Month '('1-12')' ==> ");
month=stdIn.nextInt();
System.out.println("Birthday Bonus Week '('1-4')' ==>");
week=stdIn.nextInt();
return new Employee(name, socialSecurityNumber, month, week);
}
如果有帮助,可以使用Hourly中的Hourly对象和load()
方法:
public Hourly(String name, String socialSecurityNumber, int month, int week, double hourlyPay, double hoursWorked)
{
super(name, socialSecurityNumber, month, week);
this.hourlyPay=hourlyPay;
this.hoursWorked=hoursWorked;
}
public static Hourly load()
{
Scanner stdIn = new Scanner (System.in);
System.out.println("Hourly Pay ==> ");
hourlyPay=stdIn.nextDouble();
System.out.println("Hours Worked This Past Week ==>");
hoursWorked=stdIn.nextDouble();
return new Hourly(name, socialSecurityNumber, month, week, hourlyPay, hoursWorked);
}
将抽象方法添加到类后,就无法再实例化它。 在您的方案中,如果它们提供了getEarnings()和Employee声明的任何其他抽象方法的实现,则可以实例化Hourly,Salaried和SalariedPlusCommission。
这样的类层次结构的共同意图是使用Employee来保存所有子类共有的行为(代码)。 您扩展它,并且永远不要直接实例化它。
如果确实需要实例化Employee,则必须提供getEarnings()的实现,并且可能还会在每个子类中重写该实现。 如果需要,基本实现可以返回null或引发异常。 具有NOOP基本实现会让我感到潜在的“不良代码味道”,但我不知道您还想实现什么。
您也可以仅使用该方法创建IEarn接口,并让每个子类实现它(但不能使用Employee)。 这里的问题是,您将无法将所有实体都声明为基类,从而无法在收入方面对它们进行多态处理。 您将无法执行以下操作:
Employee foo = new Hourly();
Employee baz = new Salaried();
baz.getEarnings();
foo.getEarnings();
您必须执行以下操作:
IEarn foo = new Hourly();
IEarn baz = new Salaried();
baz.getEarnings();
foo.getEarnings();
但是,这里要做的典型事情是设计您的类层次结构,以便Employee作为抽象类很有用,并且从未直接实例化。
Employee
是一个抽象类,这意味着它没有实现其所有方法。 由子类来实现具有适当行为的那些方法。 因此,加载Employee
并没有意义,而加载Hourly
则有意义,因为它实现了所有方法。
您不应该尝试实例化员工。 而是从Employee
类中删除load()
方法,并仅保留Hourly
, Salaried
和SalariedPlusCommission
load()
方法。
如果您需要为Employee
创建load()
方法,请询问用户他/她想要什么样的雇员:
System.out.println("Type (Hourly, Salaried or SalariedPlusCommission): ");
t=stdIn.nextLine();
switch(t) {
case "Hourly":
return Hourly.load()
break;
// other cases
}
但是请注意,这不是一个好习惯,并且Employee
类不应该负责实例化其子类。 此要求涉及使用Employee
的代码。 例如,不要求Employee
类了解其所有子类。 这是使用Employee
的代码的责任,因为只有该代码才能知道它要支持的员工子类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.