Now we redeclare class BasePlusCommissionEmployee
(Fig. G.8) to extend class CommissionEmployee
(Fig. G.4). A BasePlusCommissionEmployee
object is a CommissionEmployee
, because inheritance passes on class CommissionEmployee
’s capabilities. Class BasePlusCommissionEmployee
also has instance variable baseSalary
(Fig. G.8, line 6). Keyword extends
(line 4) indicates inheritance. BasePlusCommissionEmployee
inherits CommissionEmployee
’s instance variables and methods, but only the superclass’s public
and protected
members are directly accessible in the subclass. The CommissionEmployee
constructor is not inherited. So, the public BasePlusCommissionEmployee
services include its constructor (lines 9–16), public
methods inherited from CommissionEmployee
, and methods setBaseSalary
(lines 19–26), getBaseSalary
(lines 29–32), earnings
(lines 35–40) and toString
(lines 43–53). Methods earnings
and toString
override the corresponding methods in class CommissionEmployee
because their superclass versions do not properly calculate a BasePlusCommissionEmployee
’s earnings or return an appropriate String
representation.
1 // Fig. G.8: BasePlusCommissionEmployee.java
2 // private superclass members cannot be accessed in a subclass.
3
4 public class BasePlusCommissionEmployee extends CommissionEmployee
5 {
6 private double baseSalary; // base salary per week
7
8 // six-argument constructor
9 public BasePlusCommissionEmployee( String first, String last,
10 String ssn, double sales, double rate, double salary )
11 {
12 // explicit call to superclass CommissionEmployee constructor
13 super ( first, last, ssn, sales, rate );
14
15 setBaseSalary( salary ); // validate and store base salary
16 } // end six-argument BasePlusCommissionEmployee constructor
17
18 // set base salary
19 public void setBaseSalary( double salary )
20 {
21 if ( salary >= 0.0 )
22 baseSalary = salary;
23 else
24 throw new IllegalArgumentException(
25 "Base salary must be >= 0.0" );
26 } // end method setBaseSalary
27
28 // return base salary
29 public double getBaseSalary()
30 {
31 return baseSalary;
32 } // end method getBaseSalary
33
34 // calculate earnings
35 @Override // indicates that this method overrides a superclass method
36 public double earnings()
37 {
38 // not allowed: commissionRate and grossSales private in superclass
39 return baseSalary + ( commissionRate * grossSales );
40 } // end method earnings
41
42 // return String representation of BasePlusCommissionEmployee
43 @Override // indicates that this method overrides a superclass method
44 public String toString()
45 {
46 // not allowed: attempts to access private superclass members
47 return String.format(
48 "%s: %s %s
%s: %s
%s: %.2f
%s: %.2f
%s: %.2f",
49 "base-salaried commission employee", firstName, lastName,
50 "social security number", socialSecurityNumber,
51 "gross sales", grossSales, "commission rate", commissionRate,
52 "base salary", baseSalary );
53 } // end method toString
54 } // end class BasePlusCommissionEmployee
BasePlusCommissionEmployee.java:39: commissionRate has private access in
CommissionEmployee
return baseSalary + ( commissionRate * grossSales );
^
BasePlusCommissionEmployee.java:39: grossSales has private access in
CommissionEmployee
return baseSalary + ( commissionRate * grossSales );
^
BasePlusCommissionEmployee.java:49: firstName has private access in
CommissionEmployee
"base-salaried commission employee", firstName, lastName,
^
BasePlusCommissionEmployee.java:49: lastName has private access in
CommissionEmployee
"base-salaried commission employee", firstName, lastName,
^
BasePlusCommissionEmployee.java:50: socialSecurityNumber has private access
in CommissionEmployee
"social security number", socialSecurityNumber,
^
BasePlusCommissionEmployee.java:51: grossSales has private access in
CommissionEmployee
"gross sales", grossSales, "commission rate", commissionRate,
^
BasePlusCommissionEmployee.java:51: commissionRate has private access in
CommissionEmployee
"gross sales", grossSales, "commission rate", commissionRate,
^
7 errors
Each subclass constructor must implicitly or explicitly call its superclass constructor to initialize the instance variables inherited from the superclass. Line 13 in BasePlusCommissionEmployee
’s six-argument constructor (lines 9–16) explicitly calls class CommissionEmployee
’s five-argument constructor (declared at lines 13–22 of Fig. G.4) to initialize the superclass portion of a BasePlusCommissionEmployee
object (i.e., variables firstName
, lastName
, socialSecurityNumber
, grossSales
and commissionRate
). We do this by using the superclass constructor call syntax—keyword super
, followed by a set of parentheses containing the superclass constructor arguments. The arguments first
, last
, ssn
, sales
and rate
are used to initialize superclass members firstName
, lastName
, socialSecurityNumber
, grossSales
and commissionRate
, respectively. If BasePlusCommissionEmployee
’s constructor did not invoke the superclass’s constructor explicitly, Java would attempt to invoke the superclass’s no-argument or default constructor. Class CommissionEmployee
does not have such a constructor, so the compiler would issue an error. The explicit superclass constructor call in line 13 of Fig. G.8 must be the first statement in the subclass constructor’s body. When a superclass contains a no-argument constructor, you can use super()
to call that constructor explicitly, but this is rarely done.
The compiler generates errors for line 39 because superclass CommissionEmployee
’s instance variables commissionRate
and grossSales
are private
—subclass BasePlusCommissionEmployee
’s methods are not allowed to access superclass CommissionEmployee
’s private
instance variables. We highlighted the erroneous code. The compiler issues additional errors at lines 49–51 of BasePlusCommissionEmployee
’s toString
method for the same reason. The errors in BasePlusCommissionEmployee
could have been prevented by using the get methods inherited from class CommissionEmployee
. For example, line 39 could have used getCommissionRate
and getGrossSales
to access CommissionEmployee
’s private
instance variables commissionRate
and grossSales
, respectively. Lines 49–51 also could have used appropriate get methods to retrieve the values of the superclass’s instance variables.