Перепишите данный класс, чтобы использовать композицию, а не наследование - PullRequest
0 голосов
/ 06 февраля 2011
// Fig. 9.8: BasePlusCommissionEmployee.java
// private superclass members cannot be accessed in a subclass.

public class BasePlusCommissionEmployee extends CommissionEmployee
{
   private double baseSalary; // base salary per week

   // six-argument constructor
   public BasePlusCommissionEmployee( String first, String last, 
      String ssn, double sales, double rate, double salary )
   {
      // explicit call to superclass CommissionEmployee constructor
      super( first, last, ssn, sales, rate );

      setBaseSalary( salary ); // validate and store base salary
   } // end six-argument BasePlusCommissionEmployee constructor

   // set base salary
   public void setBaseSalary( double salary )
   {
      baseSalary = ( salary < 0.0 ) ? 0.0 : salary;
   } // end method setBaseSalary

   // return base salary
   public double getBaseSalary()
   {
      return baseSalary;
   } // end method getBaseSalary

   // calculate earnings
   @Override // indicates that this method overrides a superclass method
   public double earnings()
   {
      // not allowed: commissionRate and grossSales private in superclass
      return baseSalary + ( commissionRate * grossSales );
   } // end method earnings

   // return String representation of BasePlusCommissionEmployee
   @Override // indicates that this method overrides a superclass method
   public String toString()
   {
      // not allowed: attempts to access private superclass members   
      return String.format( 
         "%s: %s %s\n%s: %s\n%s: %.2f\n%s: %.2f\n%s: %.2f", 
         "base-salaried commission employee", firstName, lastName, 
         "social security number", socialSecurityNumber, 
         "gross sales", grossSales, "commission rate", commissionRate, 
         "base salary", baseSalary );
   } // end method toString
} // end class BasePlusCommissionEmployee

// Fig. 9.4: CommissionEmployee.java
// CommissionEmployee class represents a commission employee.

public class CommissionEmployee extends Object
{
   private String firstName;
   private String lastName;
   private String socialSecurityNumber;
   private double grossSales; // gross weekly sales
   private double commissionRate; // commission percentage

   // five-argument constructor
   public CommissionEmployee( String first, String last, String ssn, 
      double sales, double rate )
   {
      // implicit call to Object constructor occurs here
      firstName = first;
      lastName = last;
      socialSecurityNumber = ssn;
      setGrossSales( sales ); // validate and store gross sales
      setCommissionRate( rate ); // validate and store commission rate
   } // end five-argument CommissionEmployee constructor

   // set first name
   public void setFirstName( String first )
   {
      firstName = first; // should validate
   } // end method setFirstName

   // return first name
   public String getFirstName()
   {
      return firstName;
   } // end method getFirstName

   // set last name
   public void setLastName( String last )
   {
      lastName = last; // should validate
   } // end method setLastName

   // return last name
   public String getLastName()
   {
      return lastName;
   } // end method getLastName

   // set social security number
   public void setSocialSecurityNumber( String ssn )
   {
      socialSecurityNumber = ssn; // should validate
   } // end method setSocialSecurityNumber

   // return social security number
   public String getSocialSecurityNumber()
   {
      return socialSecurityNumber;
   } // end method getSocialSecurityNumber

   // set commission employee's gross sales amount
   public void setGrossSales( double sales )
   {
      grossSales = ( sales < 0.0 ) ? 0.0 : sales;
   } // end method setGrossSales

   // return commission employee's gross sales amount
   public double getGrossSales()
   {
      return grossSales;
   } // end method getGrossSales

   // set commission employee's rate
   public void setCommissionRate( double rate )
   {
      commissionRate = ( rate > 0.0 && rate < 1.0 ) ? rate : 0.0;
   } // end method setCommissionRate

   // return commission employee's rate
   public double getCommissionRate()
   {
      return commissionRate;
   } // end method getCommissionRate

   // calculate commission employee's pay
   public double earnings()
   {
      return commissionRate * grossSales;
   } // end method earnings

   // return String representation of CommissionEmployee object
   @Override // indicates that this method overrides a superclass method
   public String toString()
   {
      return String.format( "%s: %s %s\n%s: %s\n%s: %.2f\n%s: %.2f", 
         "commission employee", firstName, lastName, 
         "social security number", socialSecurityNumber, 
         "gross sales", grossSales, 
         "commission rate", commissionRate );
   } // end method toString
} // end class CommissionEmployee

Я заблудился, с чего начать.Я понимаю, что композиция - это отношение «есть», а наследование - это «есть».Нужно ли мне брать этот код и переписывать его, используя классы внутри классов?

1 Ответ

1 голос
/ 06 февраля 2011

НЕ обязательно.Сначала подумайте об интерфейсах или даже некотором примере кода.У вас есть сотрудник;этот работник "имеет" базовую оплату и комиссионные.Обе эти вещи могут меняться чаще, чем, скажем, SSAN сотрудника, поэтому им есть смысл выделяться в качестве самостоятельных классов.

Теперь у вас есть три класса (это намеренно неJava-нотация):

class Employee
    ssan : SocialSecurityNumber  // more classes I don't bother to define
    base : BasePay
    cmsn : Commission

    public setBasePay(base:BasePay)
    public getBasePay()
    public setCommission(cmsn:Commission)
    public getCommission()

    ... more stuff
end

class BasePay

    rate: DollarsPerHour

    public getPay(hr : Hours)
end

class Commission
    rate : Pct

    public getPay(sales : Dollars)
end

и где-то у вас будет что-то вроде

check.totalPay = employee.getBasePay().getPay(hrs) + // note thats an instance
                 employee.getCommision().getPay(totSales)

Кстати, я считаю полезным думать об этом, как будто у меня есть специальные классыпочти все, как DollarsPerHour.В конце концов вы можете заменить это на что-то вроде double, но пока вы думаете об этом, это помогает сохранить единицы и не позволяет вам делать такие вещи, как добавление долларов к часам

...