Constructors in Derived Classes

As we explained in the preceding section, instantiating a derived class object begins a chain of constructor calls in which the derived class constructor, before performing its own tasks, invokes its direct base class's constructor either explicitly (via a constructor initializer with the base reference) or implicitly (calling the base class's default constructor or parameterless constructor). Similarly, if the base class is derived from another class (as every class except object is), the base class 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 derived class constructor's body finishes executing last. Each base class's constructor manipulates the base class instance variables that the derived class object inherits. For example, consider again the CommissionEmployee3BasePlusCommissionEmployee4 hierarchy from Fig. 10.13 and Fig. 10.14. When an application creates a BasePlusCommissionEmployee4 object, the BasePlusCommissionEmployee4 constructor is called. That constructor calls CommissionEmployee3's constructor, which in turn implicitly 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 10 6

When an application creates a derived class object, the derived class constructor immediately calls the base class constructor (explicitly, via base, or implicitly). The base class constructor's body executes to initialize the base class's instance variables that are part of the derived class object, then the derived class constructor's body executes to initialize the derived class-only instance variables. Even if a constructor does not assign a value to an instance variable, the variable is still initialized to its default value (i.e., 0 for simple numeric types, false for bools and null for references).

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

Figure 10.16. CommissionEmployee4 class represents a commission employee.

(This item is displayed on pages 495 - 496 in the print version)

 1 // Fig. 10.16: CommissionEmployee4.cs
 2 // CommissionEmployee4 class represents a commission employee.
 3 using System;
 4
 5 public class CommissionEmployee4
 6 {
 7 private string firstName;
 8 private string lastName;
 9 private string socialSecurityNumber;
10 private decimal grossSales; // gross weekly sales
11 private decimal commissionRate; // commission percentage
12
13 // five-parameter constructor
14 public CommissionEmployee4( string first, string last, string ssn,
15 decimal sales, decimal rate )
16 {
17 // implicit call to object constructor occurs here
18 firstName = first;
19 lastName = last;
20 socialSecurityNumber = ssn;
21 GrossSales = sales; // validate gross sales via property
22 CommissionRate = rate; // validate commission rate via property
23
24 Console.WriteLine( "
CommissionEmployee4 constructor:
" + this );
25 } // end five-parameter CommissionEmployee4 constructor
26
27 // read-only property that gets commission employee's first name
28 public string FirstName
29 {
30 get
31 {
32 return firstName;
33 } // end get
34 } // end property FirstName
35
36 // read-only property that gets commission employee's last name
37 public string LastName
38 {
39 get
40 {
41 return lastName;
42 } // end get
43 } // end property LastName
44
45 // read-only property that gets
46 // commission employee's social security number
47 public string SocialSecurityNumber
48 {
49 get
50 {
51 return socialSecurityNumber;
52 } // end get
53 } // end property SocialSecurityNumber
54 55 // property that gets and sets commission employee's gross sales 56 public decimal GrossSales 57 { 58 get 59 { 60 return grossSales; 61 } // end get 62 set 63 { 64 grossSales = ( value < 0 ) ? 0 : value; 65 } // end set 66 } // end property GrossSales 67 68 // property that gets and sets commission employee's commission rate 69 public decimal CommissionRate 70 { 71 get 72 { 73 return commissionRate; 74 } // end get 75 set 76 { 77 commissionRate = ( value > 0 && value < 1 ) ? value : 0; 78 } // end set 79 } // end property CommissionRate 80 81 // calculate commission employee's pay 82 public virtual decimal Earnings() 83 { 84 return CommissionRate * GrossSales; 85 } // end method Earnings 86 87 // return string representation of CommissionEmployee object 88 public override string ToString() 89 { 90 return string.Format( 91 "{0}: {1} {2} {3}: {4} {5}: {6:C} {7}: {8:F2}", 92 "commission employee", FirstName, LastName, 93 "social security number", SocialSecurityNumber, 94 "gross sales", GrossSales, "commission rate", CommissionRate ); 95 } // end method ToString 96 } // end class CommissionEmployee4

Figure 10.17. BasePlusCommissionEmployee5 class declaration.

(This item is displayed on pages 497 - 498 in the print version)

 1 // Fig. 10.17: BasePlusCommissionEmployee5.cs
 2 // BasePlusCommissionEmployee5 class declaration.
 3 using System;
 4
 5 public class BasePlusCommissionEmployee5 : CommissionEmployee4
 6 {
 7 private decimal baseSalary; // base salary per week
 8
 9 // six-parameter derived class constructor
10 // with call to base class CommissionEmployee4 constructor
11 public BasePlusCommissionEmployee5( string first, string last,
12 string ssn, decimal sales, decimal rate, decimal salary )
13 : base( first, last, ssn, sales, rate )
14 {
15 BaseSalary = salary; // validate base salary via property
16
17 Console.WriteLine( 
18  "
BasePlusCommissionEmployee5 constructor:
" + this );
19 } // end six-parameter BasePlusCommissionEmployee5 constructor
20
21 // property that gets and sets
22 // base-salaried commission employee's base salary
23 public decimal BaseSalary
24 {
25 get
26 {
27 return baseSalary;
28 } // end get
29 set
30 {
31 baseSalary = ( value < 0 ) ? 0 : value;
32 } // end set
33 } // end property BaseSalary
34
35 // calculate earnings
36 public override decimal Earnings()
37 {
38 return BaseSalary + base.Earnings();
39 } // end method Earnings
40
41 // return string representation of BasePlusCommissionEmployee5 42 public override string ToString() 43 { 44 return string.Format( "{0} {1} {2}: {3:C}", 45 "base-salaried", base.ToString(), "base salary", BaseSalary ); 46 } // end method ToString 47 } // end class BasePlusCommissionEmployee5

Class CommissionEmployee4 (Fig. 10.16) contains the same features as the version of the class shown in Fig. 10.13. We modified the constructor (lines 1425) to output text when it is invoked. Note that concatenating this with a string literal (line 24) implicitly invokes the ToString method of the object being constructed to obtain the object's string representation.

Class BasePlusCommissionEmployee5 (Fig. 10.17) is almost identical to BasePlusCommissionEmployee4 (Fig. 10.14), except that BasePlusCommissionEmployee5's constructor outputs text when invoked. As in CommissionEmployee4 (Fig. 10.16), we concatenate this with a string literal to implicitly obtain the object's string representation.

Figure 10.18 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 1011). Next, lines 1416 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 1921 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. Note that employee2 is constructed completely before construction of employee3 begins.

Figure 10.18. Display order in which base class and derived class constructors are called.

(This item is displayed on pages 498 - 499 in the print version)

 1 // Fig. 10.18: ConstructorTest.cs
 2 // Display order in which base class and derived class constructors
 3 // are called.
 4 using System;
 5
 6 public class ConstructorTest
 7 {
 8 public static void Main( string[] args )
 9 {
10 CommissionEmployee4 employee1 = new CommissionEmployee4( "Bob",
11  "Lewis", "333-33-3333", 5000.00M, .04M ); 
12
13 Console.WriteLine();
14 BasePlusCommissionEmployee5 employee2 = 
15  new BasePlusCommissionEmployee5( "Lisa", "Jones",
16  "555-55-5555", 2000.00M, .06M, 800.00M ); 
17
18 Console.WriteLine();
19 BasePlusCommissionEmployee5 employee3 = 
20  new BasePlusCommissionEmployee5( "Mark", "Sands",
21  "888-88-8888", 8000.00M, .15M, 2000.00M ); 
22 } // end Main
23 } // end class ConstructorTest
 
 CommissionEmployee4 constructor:
 commission employee: Bob Lewis
 social security number: 333-33-3333
 gross sales: $5,000.00
 commission rate: 0.04

 CommissionEmployee4 constructor:
 base-salaried commission employee: Lisa Jones
 social security number: 555-55-5555
 gross sales: $2,000.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: $2,000.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: $8,000.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: $8,000.00
 commission rate: 0.15
 base salary: $2,000.00

Software Engineering with Inheritance

Preface

Index

    Introduction to Computers, the Internet and Visual C#

    Introduction to the Visual C# 2005 Express Edition IDE

    Introduction to C# Applications

    Introduction to Classes and Objects

    Control Statements: Part 1

    Control Statements: Part 2

    Methods: A Deeper Look

    Arrays

    Classes and Objects: A Deeper Look

    Object-Oriented Programming: Inheritance

    Polymorphism, Interfaces & Operator Overloading

    Exception Handling

    Graphical User Interface Concepts: Part 1

    Graphical User Interface Concepts: Part 2

    Multithreading

    Strings, Characters and Regular Expressions

    Graphics and Multimedia

    Files and Streams

    Extensible Markup Language (XML)

    Database, SQL and ADO.NET

    ASP.NET 2.0, Web Forms and Web Controls

    Web Services

    Networking: Streams-Based Sockets and Datagrams

    Searching and Sorting

    Data Structures

    Generics

    Collections

    Appendix A. Operator Precedence Chart

    Appendix B. Number Systems

    Appendix C. Using the Visual Studio 2005 Debugger

    Appendix D. ASCII Character Set

    Appendix E. Unicode®

    Appendix F. Introduction to XHTML: Part 1

    Appendix G. Introduction to XHTML: Part 2

    Appendix H. HTML/XHTML Special Characters

    Appendix I. HTML/XHTML Colors

    Appendix J. ATM Case Study Code

    Appendix K. UML 2: Additional Diagram Types

    Appendix L. Simple Types

    Index



    Visual C# How to Program
    Visual C# 2005 How to Program (2nd Edition)
    ISBN: 0131525239
    EAN: 2147483647
    Year: 2004
    Pages: 600

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