2015-09-19 89 views
0

我正在爲學校開發一個工資單程序,並且有一個工資單驅動程序,Employee類,Hourly類(擴展Employee),Salaried class(extends Employee)和SalariedPlusCommission class(extends 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); 
     } 

如果它幫助這裏是從每小時的每小時對象和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); 
} 
+0

您是否試圖通過聲明抽象來調用公共構造函數? – Jordon

回答

0

只要你添加一個抽象方法的類,那麼你不能再實例化。在你的方案中,如果他們提供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(); 

但是在這裏做典型的事情是設計類層次結構,使員工被作爲有用一個抽象類,並且從不直接實例化。

0

Employee是一個抽象類,這意味着它沒有實現它的所有方法。用適當的行爲來實現這些方法是由子類決定的。因此,加載Employee是沒有意義的,但加載Hourly確實有意義,因爲它實現了所有方法。

您不應該試圖實例化員工。相反,請從Employee類中刪除load()方法,並僅保留Hourly,SalariedSalariedPlusCommissionload()方法。

如果你需要創建一個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的代碼,因爲只有該代碼可以知道它想要支持的員工子類型。