2012-07-12 2 views
6

私は従業員賃金制度を作成しています。私は抽象的なEmployeeクラスを持っています。 WageEmployeeおよびManagerは、Employeeである。その後、プログラマとSalesPersonWageEmployeeに拡張されます。Java、多重継承。私はこれをどのようにするべきですか?

私の問題は、SalesManagerを作成したいということです。 SalesMangerには、手数料と給与を加算して計算された給与が加算されています。だからタイプはSalesPersonManagerです。

インターフェイスを作成するにはどうすればよいですか。SalesPersonはどのように拡張する必要がありますか?

SalesManagerをマネージャから拡張してから、SalesPersonをインターフェイスにするのは当然です。しかし、私はそれがWageEmployeeから継承するのでできません。

これをどのように動作させるのですか?正しく?

abstract class Employee 
{ 
    String name; 

    Employee() {} 
    Employee (String nm) { name = nm; } 
    abstract double computePay(); 
    void display() {} 
    void setHours(double hrs) {} 
    void setSales(double sales) {} 
    void setSalary(double salary) { System.out.println("NO!"); } 

}

+0

継承される機能はありますか、それとも単なるメソッドですか? –

+1

個人的には、すべてのインターフェイスから開始します。これにより、最大限の柔軟性が得られます。次に、どの抽象実装が最も少ない量の再作業を生成するかをそこから把握する必要があります。唯一のソリューションは、プロキシスタイルのソリューションを使用することです。つまり、1つのインタフェースの機能は、実際には、親オブジェクトが参照を保持し、それを呼び出す代理オブジェクトによって実装されます。 – MadProgrammer

+1

この場合、インターフェイスとオブジェクトの構成はお友達です。 –

答えて

10

私には夢中ですが、ここでさまざまな支払い方法を扱うためにサブクラス化する必要はありません。代わりに、Strategy patternを使用して賃金/販売手数料を把握することを検討してください。そうすれば、あなたはクラスEmployeeとそのサブクラスSalesEmployeeを持っています。これらのそれぞれは、PayStrategyオブジェクトを持ち、具体的なサブクラスWagePayStrategyCommissionPayStrategyを持つことができます。 PayStrategy(インターフェイスまたは抽象クラスでもよい)に正しいメソッドを定義すると、Employeeインスタンスは特定の入力(営業時間、売り上げなど)に対して従業員が得る給料を戦略オブジェクトに尋ねることができます。あなたはあなたにそのアルゴリズムの周りに、より柔軟性とカプセル化を与え、別のクラスを必要とせずに任意の従業員の給与戦略を変更する方法

interface PayStrategy { 
    public float getPay(float hoursWorked, float salesMade); 
} 

class WageStrategy implements PayStrategy { 
    public float getPay(float hoursWorked, float salesMade) { 
     return hoursWorked * 8.5; 
    } 
} 

class CommissionStrategy implements PayStrategy { 
    public float getPay(float hoursWorked, float salesMade) { 
     return salesMade * 0.5 + hoursWorked * 5.0; 
    } 
} 

abstract class Employee { 
    public PayStrategy payStrategy; // assign as needed 

    public float getPay(float hoursWorked, float salesMade) { 
     return this.payStrategy.getPay(hoursWorked, salesMade); 
    } 
} 

注:

は、次の簡単な例を考えてみましょう。

+0

これはすばらしい答えです。 –

+0

なぜ、ありがとう、Luiggi: – Tim

+0

PayStrategy.getPayに1つの一般的なfloat値を指定することもできます。次に、SalesManagerには、以下のような複合ストラテジの実装があります。 public float getPay(float ignored){return wageStrategy.getPay(getHoursWorked())+ commissionStrategy.getPay(getSalesMade()); } SalesManagerクラスにはsalesMadeとhoursWorkedフィールドがあります。 – AngerClown

1

EmployeeメソッドgetFixedSalary()getComissionSalary()を有しています。

抽象サブクラスSalariedEmployeegetComissionSalaryは常に0を返します)を作成し、ProgrammerSalesPersonを展開することができます。 SalesManagerは直接Employeeを実装しています。

またはすべてのクラスは、給与尺度がある日(私はこのようになるでしょう)に変わる場合に最大限の柔軟性を与えるためにEmployeeから直接継承します。コードの重複を避けるためにヘルパーメソッドを作成しますが、後で必要に応じてモード操作を変更するオプションが残っています。

1

クラスを拡張するときには、通常、何らかの機能を保持しておき、拡張することで追加します。インタフェースを使用すると、オブジェクトが持つメソッドのリストが得られます。

EmployeeManagerがあり、機能を拡張する場所を決める必要があります。あなたのコードやオブジェクトモデルを見ることなく、誰もがEmployeeのように見え、そのうちのいくつかはManagerです。だから、あなたが従業員とは別にマネージャーが何をするかを決める必要があるように思えます。その後、すべてがEmployeeに拡張され、サブクラスがEmployeeWageEmployee,SalaryEmployeeなど)に拡張され、次にマネージャであるサブクラスがManagerインターフェイスを実装します。したがって、WageEmployeeを延長してSalesPersonとし、を実装するSalesPersonを延長するSalesManagerを指定することができます。

関連する問題