Chapter 10 - Updated
Chapter 10 - Updated
Chapter 10 – Object-Oriented
Programming: Polymorphism
Outline
10.1 Introduction
10.2 Derived-Class-Object to Base-Class-Object Conversion
10.3 Type Fields and switch Statements
10.4 Polymorphism Examples
10.5 Abstract Classes and Methods
10.6 Case Study: Inheriting Interface and Implementation
10.7 sealed Classes and Methods
10.8 Case Study: Payroll System Using Polymorphism
10.9 Case Study: Creating and Using Interfaces
10.10 Delegates
10.11 Operator Overloading
2
10.1 Introduction
Program Output
10
• Quadrilateral base-class
– Rectangle derived-class
– Square derived-class
– Parallelogram derived-class
– Trapezoid derived-class
– Method perimeter might need to be invoked on all classes
– With a Quadrilateral reference, C# polymorphically
chooses the correct overriding method in the derived-class
from which the object is instantiated
11
• Abstract classes
– Cannot be instantiated
– Used as base classes
– Class definitions are not complete – derived classes must
define the missing pieces
– Can contain abstract methods and/or abstract properties
• Have no implementation
• Derived classes must override inherited abstract methods and
properties to enable instantiation
13
AbstractShapesTe
st.cs
33 foreach( Shape shape in arrayOfShapes )
34 {
35 output += "\n\n" + shape.Name + ": " + shape +
36 "\nArea = " + shape.Area().ToString( "F" ) +
37 "\nVolume = " + shape.Volume().ToString( "F" );
38 }
39
Use a foreach loop to access Rely on polymorphism to call
40 every element
MessageBox.Show( output,of "Demonstrating
the array Polymorphism" );
appropriate version of methods
41 }
42 }
Program Output
26
1. namespace P1
2. {
3. public abstract class A
4. {
5. public abstract void print();
6. }
9. public B()
10. {
11. str = "Hello";
12. }
13. public override void print()
14. {
15. Console.WriteLine(str);
16. }
17. }
27
28
29
30
• sealed is a keyword in C#
• sealed methods cannot be overridden in a derived
class
– Methods that are declared static and private, are implicitly
sealed
• sealed classes cannot have any derived-classes
• Creating sealed classes can allow some runtime
optimizations
31
32
33
34
10.8 Case Study: Payroll System Using
Polymorphism
• Base-class Employee
– abstract
– abstract method Earnings
• Classes that derive from Employee
– Boss
– CommissionWorker
– PieceWorker
– HourlyWorker
• All derived-classes implement method Earnings
• Driver program uses Employee references to refer to
instances of derived-classes
• Polymorphism calls the correct version of Earnings
35
1 // Fig. 10.9: Employee.cs
2 // Abstract base class for company employees.
3 using System;
4
5 public abstract class Employee Employee.cs
6 {
7 private string firstName;
8 private string lastName;
9
10 // constructor
11 public Employee( string firstNameValue,
12 string lastNameValue )
13 {
14 FirstName = firstNameValue;
15 LastName = lastNameValue;
16 }
17 Definition of abstract class Employee
18 // property FirstName
19 public string FirstName
20 {
21 get
22 {
23 return firstName;
24 }
25
26 set
27 {
28 firstName = value;
29 }
30 }
31
36
32 // property LastName
33 public string LastName
34 {
35 get
36 { Declaration of abstract class Employee.cs
37 return lastName; Earnings – implementation must
38 } be provided by all derived classes
39
40 set
41 {
42 lastName = value;
43 }
44 }
45
46 // return string representation of Employee
47 public override string ToString()
48 {
49 return FirstName + " " + LastName;
50 }
51
52 // abstract method that must be implemented for each derived
53 // class of Employee to calculate specific earnings
54 public abstract decimal Earnings();
55
56 } // end class Employee
37
1 // Fig. 10.10: Boss.cs
2 // Boss class derived from Employee.
3 using System;
4
5 public class Boss : Employee Boss.cs
6 {
7 private decimal salary; // Boss's salary
8
9 // constructor
10 public Boss( string firstNameValue, string lastNameValue,
11 decimal salaryValue)
12 : base( firstNameValue, lastNameValue )
13 {
14 WeeklySalary = salaryValue;
15 }
16
17 // property WeeklySalary
18 public decimal WeeklySalary
19 { Definition of class Boss –
20 get
21 {
derives from Employee
22 return salary;
23 }
24
25 set
26 {
27 // ensure positive salary value
28 if ( value > 0 )
29 salary = value;
30 }
31 }
32
38
33 // override base-class method to calculate Boss's earnings
34 public override decimal Earnings()
35 {
36 return WeeklySalary;
37 } Boss.cs
38
39 // return string representation of Boss
40 public override string ToString()
41 {
42 return "Boss: " + base.ToString();
43 }
44 }
Implementation of method Earnings (required
by classes deriving from Employee)
39
1 // Fig. 10.11: CommisionWorker.cs
2 // CommissionWorker class derived from Employee
3 using System;
4
5 public class CommissionWorker : Employee CommisionWorker.
6 { cs
7 private decimal salary; // base weekly salary
8 private decimal commission; // amount paid per item sold
9 private int quantity; // total items sold
10
11 // constructor
12 public CommissionWorker( string firstNameValue,
13 string lastNameValue, decimal salaryValue,
14 decimal commissionValue, int quantityValue )
15 : base( firstNameValue, lastNameValue )
16 {
17 WeeklySalary = salaryValue;
18 Commission = commissionValue;
19 Quantity = quantityValue;
20 }
21 Definition of class CommissionWorker
22 // property WeeklySalary
23 public decimal WeeklySalary – derives from Employee
24 {
25 get
26 {
27 return salary;
28 }
29
40
30 set
31 {
32 // ensure non-negative salary value
33 if ( value > 0 )
34 salary = value; CommisionWorker.
35 } cs
36 }
37
38 // property Commission
39 public decimal Commission
40 {
41 get
42 {
43 return commission;
44 }
45
46 set
47 {
48 // ensure non-negative commission value
49 if ( value > 0 )
50 commission = value;
51 }
52 }
53
54 // property Quantity
55 public int Quantity
56 {
57 get
58 {
59 return quantity;
60 }
61
41
62 set
63 {
64 // ensure non-negative quantity value
65 if ( value > 0 )
66 quantity = value; CommisionWorker.
67 } cs
68 }
69
70 // override base-class method to calculate
71 // CommissionWorker's earnings
72 public override decimal Earnings()
73 {
74 return WeeklySalary + Commission * Quantity;
75 }
76
77 // return string representation of CommissionWorker
78 public override string ToString()
79 {
80 return "CommissionWorker: " + base.ToString();
81 }
82 Implementation of method Earnings (required
83 } // end class CommissionWorker
by classes deriving from Employee)
42
1 // Fig. 10.12: PieceWorker.cs
2 // PieceWorker class derived from Employee.
3 using System;
4
5 public class PieceWorker : Employee PieceWorker.cs
6 {
7 private decimal wagePerPiece; // wage per piece produced
8 private int quantity; // quantity of pieces produced
9
10 // constructor
11 public PieceWorker( string firstNameValue,
12 string lastNameValue, decimal wagePerPieceValue,
13 int quantityValue )
14 : base( firstNameValue, lastNameValue )
15 {
16 WagePerPiece = wagePerPieceValue;
17 Quantity = quantityValue;
18 } Definition of class PieceWorker
19
20 // property WagePerPiece – derives from Employee
21 public decimal WagePerPiece
22 {
23 get
24 {
25 return wagePerPiece;
26 }
27
28 set
29 {
30 if ( value > 0 )
31 wagePerPiece = value;
32 }
33 }
34
43
35 // property Quantity
36 public int Quantity
37 {
38 get
39 { PieceWorker.cs
40 return quantity;
41 }
42
43 set
44 {
45 if ( value > 0 )
46 quantity = value;
47 }
48 }
49
50 // override base-class method to calculate
51 // PieceWorker's earnings
52 public override decimal Earnings()
53 {
54 return Quantity * WagePerPiece;
55 }
56
57 // return string representation of PieceWorker
58 public override string ToString()
59 {
60 return "PieceWorker: " + base.ToString();
61 }
62 }
Implementation of method Earnings (required
by classes deriving from Employee)
44
1 // Fig. 10.13: HourlyWorker.cs
2 // HourlyWorker class derived from Employee.
3 using System;
4
5 public class HourlyWorker : Employee HourlyWorker.cs
6 {
7 private decimal wage; // wage per hour of work
8 private double hoursWorked; // hours worked during week
9
10 // constructor
11 public HourlyWorker( string firstNameValue, string LastNameValue,
12 decimal wageValue, double hoursWorkedValue )
13 : base( firstNameValue, LastNameValue )
14 {
15 Wage = wageValue;
16 HoursWorked = hoursWorkedValue;
17 }
18 Definition of class HourlyWorker –
19 // property Wage
20 public decimal Wage derives from Employee
21 {
22 get
23 {
24 return wage;
25 }
26
27 set
28 {
29 // ensure non-negative wage value
30 if ( value > 0 )
31 wage = value;
32 }
33 }
34
45
35 // property HoursWorked
36 public double HoursWorked
37 {
38 get
39 { HourlyWorker.cs
40 return hoursWorked;
41 }
42
43 set
44 {
45 // ensure non-negative hoursWorked value
46 if ( value > 0 )
47 hoursWorked = value;
48 }
49 }
50
51 // override base-class method to calculate
52 // HourlyWorker earnings
53 public override decimal Earnings()
54 {
55 // compensate for overtime (paid "time-and-a-half")
56 if ( HoursWorked <= 40 )
57 {
58 return Wage * Convert.ToDecimal( HoursWorked );
59 }
60 Implementation of method Earnings (required
61 else by classes deriving from Employee)
62 {
63 // calculate base and overtime pay
64 decimal basePay = Wage * Convert.ToDecimal( 40 );
65 decimal overtimePay = Wage * 1.5M *
66 Convert.ToDecimal( HoursWorked - 40 );
67
46
68 return basePay + overtimePay;
69 }
70 }
71
72 // return string representation of HourlyWorker HourlyWorker.cs
73 public override string ToString()
74 {
75 return "HourlyWorker: " + base.ToString();
76 }
77 }
47
1 // Fig. 10.14: EmployeesTest.cs
2 // Demonstrates polymorphism by displaying earnings
3 // for various Employee types.
4 using System;
5 using System.Windows.Forms; EmployeesTest.cs
6
Assign Employee reference to
7 public class EmployeesTest reference a Boss object
8 {
9 public static void Main( string[] args ) Use method GetString to polymorphically
10 {
11
obtain salary information. Then use the original
Boss boss = new Boss( "John", "Smith", 800 );
12 Boss reference to obtain the information
13 CommissionWorker commissionWorker =
14 new CommissionWorker( "Sue", "Jones", 400, 3, 150 );
15
16 PieceWorker pieceWorker = new PieceWorker( "Bob", "Lewis",
17 Convert.ToDecimal( 2.5 ), 200 );
18
19 HourlyWorker hourlyWorker = new HourlyWorker( "Karen",
20 "Price", Convert.ToDecimal( 13.75 ), 50 );
21
22 Employee employee = boss;
23
24 string output = GetString( employee ) + boss + " earned " +
25 boss.Earnings().ToString( "C" ) + "\n\n";
26
27 employee = commissionWorker;
28
29 output += GetString( employee ) + commissionWorker +
30 " earned " +
31 commissionWorker.Earnings().ToString( "C" ) + "\n\n";
32
33 employee = pieceWorker;
34
48
35 output += GetString( employee ) + pieceWorker +
36 " earned " + pieceWorker.Earnings().ToString( "C" ) +
37 "\n\n"; Definition of method GetString,
38
39 employee = hourlyWorker; which takes as an argument an EmployeesTest.cs
40 Employee object.
41 output += GetString( employee ) + hourlyWorker +
42 " earned " + hourlyWorker.Earnings().ToString( "C" ) +
43 "\n\n";
44 Polymorphically call the method of
45 MessageBox.Show( output, "Demonstrating Polymorphism",
the appropriate derived class
46 MessageBoxButtons.OK, MessageBoxIcon.Information );
47
48 } // end method Main
49
50 // return string that contains Employee information
51 public static string GetString( Employee worker )
52 {
53 return worker.ToString() + " earned " +
54 worker.Earnings().ToString( "C" ) + "\n";
55 }
56 }
Program Output