Constructors in Subclasses

As we explained in the preceding section, instantiating a subclass object begins a chain of constructor calls in which the subclass constructor, before performing its own tasks, invokes its direct superclass's constructor either explicitly (via the super reference) or implicitly (calling the superclass's default constructor or no-argument constructor). Similarly, if the superclass is derived from another class (as is, of course, every class except Object), the superclass constructor invokes the constructor of the next class up in the hierarchy, and so on. The last constructor called in the chain is always the constructor for class Object. The original subclass constructor's body finishes executing last. Each superclass's constructor manipulates the superclass instance variables that the subclass object inherits. For example, consider again the CommissionEmployee3BasePlusCommissionEmployee4 hierarchy from Fig. 9.12 and Fig. 9.13. When a program creates a BasePlusCommissionEmployee4 object, the BasePlusCommissionEmployee4 constructor is called. That constructor calls CommissionEmployee3's constructor, which in turn calls Object's constructor. Class Object's constructor has an empty body, so it immediately returns control to CommissionEmployee3's constructor, which then initializes the private instance variables of CommissionEmployee3 that are part of the BasePlusCommissionEmployee4 object. When CommissionEmployee3's constructor completes execution, it returns control to BasePlusCommissionEmployee4's constructor, which initializes the BasePlusCommissionEmployee4 object's baseSalary.

Software Engineering Observation 9.8

When a program creates a subclass object, the subclass constructor immediately calls the superclass constructor (explicitly, via super, or implicitly). The superclass constructor's body executes to initialize the superclass's instance variables that are part of the subclass object, then the subclass constructor's body executes to initialize the subclass-only instance variables. Java ensures that even if a constructor does not assign a value to an instance variable, the variable is still initialized to its default value (e.g., 0 for primitive numeric types, false for booleans, null for references).

Our next example revisits the commission employee hierarchy by declaring a CommissionEmployee4 class (Fig. 9.15) and a BasePlusCommissionEmployee5 class (Fig. 9.16). Each class's constructor prints a message when invoked, enabling us to observe the order in which the constructors in the hierarchy execute.

Figure 9.15. CommissionEmployee4's constructor outputs text.

(This item is displayed on pages 445 - 447 in the print version)

 1 // Fig. 9.15: CommissionEmployee4.java
 2 // CommissionEmployee4 class represents a commission employee.
 3
 4 public class CommissionEmployee4
 5 {
 6 private String firstName;
 7 private String lastName;
 8 private String socialSecurityNumber;
 9 private double grossSales; // gross weekly sales
10 private double commissionRate; // commission percentage
11 
12 // five-argument constructor
13 public CommissionEmployee4( String first, String last, String ssn,
14 double sales, double rate )
15 {
16 // implicit call to Object constructor occurs here
17 firstName = first;
18 lastName = last;
19 socialSecurityNumber = ssn;
20 setGrossSales( sales ); // validate and store gross sales
21 setCommissionRate( rate ); // validate and store commission rate
22 
23 System.out.printf( 
24  "
CommissionEmployee4 constructor:
%s
", this );
25 } // end five-argument CommissionEmployee4 constructor
26 
27 // set first name
28 public void setFirstName( String first )
29 {
30 firstName = first;
31 } // end method setFirstName
32 
33 // return first name
34 public String getFirstName()
35 {
36 return firstName;
37 } // end method getFirstName
38 
39 // set last name
40 public void setLastName( String last )
41 {
42 lastName = last;
43 } // end method setLastName
44 
45 // return last name
46 public String getLastName()
47 {
48 return lastName;
49 } // end method getLastName
50 
51 // set social security number
52 public void setSocialSecurityNumber( String ssn )
53 {
54 socialSecurityNumber = ssn; // should validate
55 } // end method setSocialSecurityNumber
56 
57 // return social security number
58 public String getSocialSecurityNumber()
59 {
60 return socialSecurityNumber;
61 } // end method getSocialSecurityNumber
62 
63 // set gross sales amount
64 public void setGrossSales( double sales )
65 {
66 grossSales = ( sales < 0.0 ) ? 0.0 : sales;
67 } // end method setGrossSales
68 
69 // return gross sales amount
70 public double getGrossSales()
71 {
72 return grossSales;
73 } // end method getGrossSales
74 
75 // set commission rate
76 public void setCommissionRate( double rate )
77 {
78 commissionRate = ( rate > 0.0 && rate < 1.0 ) ? rate : 0.0;
79 } // end method setCommissionRate
80 
81 // return commission rate
82 public double getCommissionRate()
83 {
84 return commissionRate;
85 } // end method getCommissionRate
86 
87 // calculate earnings
88 public double earnings()
89 {
90 return getCommissionRate() * getGrossSales();
91 } // end method earnings
92 
93 // return String representation of CommissionEmployee4 object
94 public String toString()
95 {
96 return String.format( "%s: %s %s
%s: %s
%s: %.2f
%s: %.2f",
97 "commission employee", getFirstName(), getLastName(),
98 "social security number", getSocialSecurityNumber(),
99 "gross sales", getGrossSales(),
100 "commission rate", getCommissionRate() );
101 } // end method toString
102 } // end class CommissionEmployee4

Figure 9.16. BasePlusCommissionEmployee5's constructor outputs text.

(This item is displayed on pages 447 - 448 in the print version)

 1 // Fig. 9.16: BasePlusCommissionEmployee5.java
 2 // BasePlusCommissionEmployee5 class declaration.
 3
 4 public class BasePlusCommissionEmployee5 extends CommissionEmployee4
 5 {
 6 private double baseSalary; // base salary per week
 7
 8 // six-argument constructor
 9 public BasePlusCommissionEmployee5( String first, String last,
10 String ssn, double sales, double rate, double salary )
11 {
12 super( first, last, ssn, sales, rate );
13 setBaseSalary( salary ); // validate and store base salary
14
15 System.out.printf( 
16  "
BasePlusCommissionEmployee5 constructor:
%s
", this );
17 } // end six-argument BasePlusCommissionEmployee5 constructor
18
19 // set base salary
20 public void setBaseSalary( double salary )
21 {
22 baseSalary = ( salary < 0.0 ) ? 0.0 : salary;
23 } // end method setBaseSalary
24
25 // return base salary
26 public double getBaseSalary()
27 {
28 return baseSalary;
29 } // end method getBaseSalary
30
31 // calculate earnings
32 public double earnings()
33 {
34 return getBaseSalary() + super.earnings();
35 } // end method earnings
36
37 // return String representation of BasePlusCommissionEmployee5
38 public String toString()
39 {
40 return String.format( "%s %s
%s: %.2f", "base-salaried",
41 super.toString(), "base salary", getBaseSalary() );
42 } // end method toString
43 } // end class BasePlusCommissionEmployee5

Class CommissionEmployee4 (Fig. 9.15) contains the same features as the version of the class shown in Fig. 9.4. We modified the constructor (lines 1325) to output text upon its invocation. Note that outputting this with the %s format specifier (lines 2324) implicitly invokes the toString method of the object being constructed to obtain the object's string representation.

Class BasePlusCommissionEmployee5 (Fig. 9.16) is almost identical to BasePlusCommissionEmployee4 (Fig. 9.13), except that BasePlusCommissionEmployee5's constructor also outputs text when invoked. As in CommissionEmployee4 (Fig. 9.15), we output this using the %s format specifier in line 16 to obtain the object's string representation.

Figure 9.17 demonstrates the order in which constructors are called for objects of classes that are part of an inheritance hierarchy. Method main begins by instantiating CommissionEmployee4 object employee1 (lines 89). Next, lines 1214 instantiate BasePlusCommissionEmployee5 object employee2. This invokes the CommissionEmployee4 constructor, which prints output with the values passed from the BasePlusCommissionEmployee5 constructor, then performs the output specified in the BasePlusCommissionEmployee5 constructor. Lines 1719 then instantiate BasePlusCommissionEmployee5 object employee3. Again, the CommissionEmployee4 and BasePlusCommissionEmployee5 constructors are both called. In each case, the body of the CommissionEmployee4 constructor executes before the body of the BasePlusCommissionEmployee5 constructor executes. Note that employee2 is constructed completely before construction of employee3 begins.

Figure 9.17. Constructor call order.

(This item is displayed on pages 448 - 449 in the print version)

 1 // Fig. 9.17: ConstructorTest.java
 2 // Display order in which superclass and subclass constructors are called.
 3
 4 public class ConstructorTest
 5 {
 6 public static void main( String args[] )
 7 {
 8 CommissionEmployee4 employee1 = new CommissionEmployee4( 
 9  "Bob", "Lewis", "333-33-3333", 5000, .04 ); 
10
11 System.out.println();
12 BasePlusCommissionEmployee5 employee2 = 
13  new BasePlusCommissionEmployee5( 
14  "Lisa", "Jones", "555-55-5555", 2000, .06, 800 ); 
15
16 System.out.println();
17 BasePlusCommissionEmployee5 employee3 = 
18  new BasePlusCommissionEmployee5( 
19  "Mark", "Sands", "888-88-8888", 8000, .15, 2000 ); 
20 } // end main
21 } // end class ConstructorTest
 
CommissionEmployee4 constructor:
commission employee: Bob Lewis
social security number: 333-33-3333
gross sales: 5000.00
commission rate: 0.04

CommissionEmployee4 constructor:
base-salaried commission employee: Lisa Jones
social security number: 555-55-5555
gross sales: 2000.00
commission rate: 0.06
base salary: 0.00

BasePlusCommissionEmployee5 constructor:
base-salaried commission employee: Lisa Jones
social security number: 555-55-5555
gross sales: 2000.00
commission rate: 0.06
base salary: 800.00

CommissionEmployee4 constructor:
base-salaried commission employee: Mark Sands
social security number: 888-88-8888
gross sales: 8000.00
commission rate: 0.15
base salary: 0.00

BasePlusCommissionEmployee5 constructor:
base-salaried commission employee: Mark Sands
social security number: 888-88-8888
gross sales: 8000.00
commission rate: 0.15
base salary: 2000.00
 

Introduction to Computers, the Internet and the World Wide Web

Introduction to Java Applications

Introduction to Classes and Objects

Control Statements: Part I

Control Statements: Part 2

Methods: A Deeper Look

Arrays

Classes and Objects: A Deeper Look

Object-Oriented Programming: Inheritance

Object-Oriented Programming: Polymorphism

GUI Components: Part 1

Graphics and Java 2D™

Exception Handling

Files and Streams

Recursion

Searching and Sorting

Data Structures

Generics

Collections

Introduction to Java Applets

Multimedia: Applets and Applications

GUI Components: Part 2

Multithreading

Networking

Accessing Databases with JDBC

Servlets

JavaServer Pages (JSP)

Formatted Output

Strings, Characters and Regular Expressions

Appendix A. Operator Precedence Chart

Appendix B. ASCII Character Set

Appendix C. Keywords and Reserved Words

Appendix D. Primitive Types

Appendix E. (On CD) Number Systems

Appendix F. (On CD) Unicode®

Appendix G. Using the Java API Documentation

Appendix H. (On CD) Creating Documentation with javadoc

Appendix I. (On CD) Bit Manipulation

Appendix J. (On CD) ATM Case Study Code

Appendix K. (On CD) Labeled break and continue Statements

Appendix L. (On CD) UML 2: Additional Diagram Types

Appendix M. (On CD) Design Patterns

Appendix N. Using the Debugger

Inside Back Cover



Java(c) How to Program
Java How to Program (6th Edition) (How to Program (Deitel))
ISBN: 0131483986
EAN: 2147483647
Year: 2003
Pages: 615

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net