繁体   English   中英

在抽象类中返回对象的解决方法

[英]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()方法,并仅保留HourlySalariedSalariedPlusCommission 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM