Presentation is loading. Please wait.

Presentation is loading. Please wait.

 2002 Prentice Hall. All rights reserved.

Similar presentations


Presentation on theme: " 2002 Prentice Hall. All rights reserved."— Presentation transcript:

1  2002 Prentice Hall. All rights reserved.
Chapter 12 – Polymorphism, Interfaces & Operator Overloading Part I Credits go to  2014, 2011, 2009 Pearson Education, Inc. All rights reserved.  2002 Prentice Hall. All rights reserved.

2 Why art thou cast down, O my soul?
A philosopher of imposing stature doesn’t think in a vacuum. Even his most abstract ideas are, to some extent, conditioned by what is or is not known in the time when he lives. Alfred North Whitehead Why art thou cast down, O my soul? Psalms 42:5 General propositions do not decide concrete cases. Oliver Wendell Holmes

3 Chapter 12 –Polymorphism, Interfaces & Operator Overloading
Outline Introduction Derived-Class-Object to Base-Class-Object Conversion Type Fields and switch Statements Polymorphism Examples Abstract Classes and Methods Case Study: Inheriting Interface and Implementation sealed Classes and Methods Case Study: Payroll System Using Polymorphism Case Study: Creating and Using Interfaces Delegates Operator Overloading

4 To understand the concept of polymorphism
Objectives To understand the concept of polymorphism To understand how polymorphism makes systems extensible and maintainable. To understand the distinction between abstract classes and concrete classes. To learn how to create sealed classes, interfaces and delegates.

5 Polymorphism allows programmers to write:
12.1 Introduction Polymorphism allows programmers to write: Programs that handle a wide variety of related classes in a generic manner the programmer can deal in generalities and let the executing program concern itself with the specifics. Makes it possible to design and implement systems that are easily extensible new classes can be added with little or no modification to the generic portions of the program

6 12.2 Polymorphism Examples
For example, base-class Shape derived-classes Circle, Rectangle and Square Each class draws itself according to type of class Shape has method draw Each subclass (derived class) overrides method draw Call method draw of base-class Shape Program determines dynamically which subclass draw method to invoke At execution time, program determines to which object the reference is actually pointing

7 12.2 Polymorphism Examples
Quadrilateral base-class Rectangle derived-class Square derived-class Parallelogram derived-class Trapezoid derived-class Rectangle "is a" Quadrilateral getPerimeter(or area) method can be performed on any derived-class: Square, Parallelogram, Trapezoid public class Square {getPerimeter(){} } public class Parallelogram {getPerimeter(){} } Same method takes on "many forms" - polymorphism Have an array of base-class references Array would point to all the objects Call getPerimeter using the base-class references Appropriate method called for each class Method perimeter might need to be invoked on all classes s.getPerimeter(); // s – base-class reference refers to a proper // derived-class object C# polymorphically chooses the correct overriding method in the derived-class from which the object is instantiated Adding a new derived-class easily Simply need to define getPerimeter for that class Can refer to it with a base-class reference Can use same base-class array as before - "fits right in"

8 12.2 Polymorphism Examples
SpaceObject base-class – contains method DrawYourself Martian derived-class (implements DrawYourself) Venutian derived-class (implements DrawYourself) Plutonian derived-class (implements DrawYourself) SpaceShip derived-class (implements DrawYourself) A screen-manager program may contain a SpaceObject array of references to objects of various classes that derive from SpaceObject To refresh the screen, the screen-manager calls DrawYourself on each object in the array The program polymorphically calls the appropriate version of DrawYourself on each object, based on the type of that object

9 12.3 Demonstrating Polymorphic Behavior
An object of a derived-class can be treated as an object of its base-class this enables to create An array of base-class references that refer to objects of many derived-class types this is allowed despite the fact that the derived-class objects are of different data type Base-class object is NOT an object of any of its derived classes Assigning a base-class reference to a derived-class reference causes InvalidCastException Class hierarchies Can assign derived-class objects to base-class references and manipulate the object as that type Can explicitly cast between types in a class hierarchy

10 Definition of class Point
1 // Fig ed1: Point.cs 2 // Point class represents an x-y coordinate pair. 3 4 using System; 5 6 // Point class definition implicitly inherits from Object 7 public class Point 8 { // point coordinate private int x, y; 11 // default constructor public Point() { // implicit call to Object constructor occurs here } 17 // constructor public Point( int xValue, int yValue ) { // implicit call to Object constructor occurs here X = xValue; Y = yValue; } 25 // property X public int X { get { return x; } 33 Definition of class Point Point.cs

11 Point.cs 34 set 35 { 36 x = value; // no need for validation 37 } 38
{ x = value; // no need for validation } 38 } // end property X 40 // property Y public int Y { get { return y; } 48 set { y = value; // no need for validation } 53 } // end property Y 55 // return string representation of Point public override string ToString() { return "[" + X + ", " + Y + "]"; } 61 62 } // end class Point Point.cs

12 Definition of class Circle which inherits from class Point
1 // Fig ed1: Circle.cs 2 // Circle class that inherits from class Point. 3 4 using System; 5 6 // Circle class definition inherits from Point public class Circle : Point //each Circle object “is a” Point // and has a radius represented via property Radius 8 { private double radius; // circle's radius 10 // default constructor public Circle() { // implicit call to Point constructor occurs here } 16 // constructor public Circle( int xValue, int yValue, double radiusValue ) : base( xValue, yValue ) { Radius = radiusValue; } 23 // property Radius public double Radius { get { return radius; } 31 Definition of class Circle which inherits from class Point Circle.cs

13 Circle.cs 32 set 33 { 34 if ( value >= 0 ) // validate radius
{ if ( value >= 0 ) // validate radius radius = value; } 37 } // end property Radius 39 // calculate Circle diameter public double Diameter() { return Radius * 2; } 45 // calculate Circle circumference public double Circumference() { return Math.PI * Diameter(); } 51 // calculate Circle area public virtual double Area() { return Math.PI * Math.Pow( Radius, 2 ); } 57 // return string representation of Circle public override string ToString() { return "Center = " + base.ToString() + "; Radius = " + Radius; } 64 65 } // end class Circle Circle.cs

14 Use base-class reference to access a derived-class object
1 // Fig ed1: PointCircleTest.cs // Demonstrating inheritance and polymorphism // by using the assignment and cast operations. 3 4 using System; 5 using System.Windows.Forms; 6 7 // PointCircleTest class definition 8 class PointCircleTest 9 { // main entry point for application. static void Main( string[] args ) { // Assign a base-class reference to a base-class-type variable (object) Point point1 = new Point( 30, 50 ); // Assign a derived-class reference to derived-class-type variable (object) Circle circle1 = new Circle( 120, 89, 2.7 ); 15 string output = "Point point1: " + point1.ToString() + "\nCircle circle1: " + circle1.ToString(); 18 // use 'is a' relationship to assign derived-class references // Circle circle1 to base-class reference Point Point point2 = circle1; 22 output += "\n\nCCircle circle1 (via point2): " + point2.ToString(); // the methods which is called //is based on the referred object type (not the reference type) // this is an example of polymorphism – see next sections // downcast BACK to Circle (cast base-class reference point2 to // derived-class reference Circle circle2) Circle circle2 = ( Circle ) point2; // If a derived-class object has been assigned to a reference of one of its direct or indirect base (see line 21) classes, it is acceptable to cast that base-class reference back to a reference of the derived-class type (see also line 37). output += "\n\nCircle circle1 (via circle2): " + circle2.ToString(); 32 output += "\nArea of circle1 (via circle2): " + circle2.Area().ToString( "F" ); // F is 2 decimal places 35 PointCircleTest.cs Create a Point object Create a Circle object Use base-class reference to access a derived-class object Use derived-class reference to access circle1 object

15 PointCircleTest.cs Program Output
Test if point1 references a Circle object – Improper case since point1 references a Point object // attempt to assign point1 object to Circle reference if ( point1 is Circle ) // true if the left operand is a reference to { // an instance of the right operand or a derived class circle2 = ( Circle ) point1; // objects can be cast only to // their own type or to their base-class types output += "\n\ncast successful"; } else { output += "\n\npoint1 does not refer to a Circle"; } 46 MessageBox.Show( output, "Demonstrating the 'is a' relationship" ); 49 } // end method Main 51 52 } // end class PointCircleTest PointCircleTest.cs Program Output

16 errors Assigning a base-class object (or a base-class reference) to a derived-class reference (without an explicit cast) is a syntax error. Attempting to cast a base-class reference to a derived-class reference causes an InvalidCastException if the reference refers to a base-class object rather than an appropriate derived-class object. After assigning a derived-class object to a base-class reference, attempting to reference derived-class-only members with the base-class reference is a compilation error!!!

17 Implicit Base-class-Object-to-Derived-class-Object Conversion
derived-class reference and base-class reference Implicit conversion base-class reference to derived-class reference derived-class object “is a” base-class object through inheritance Four ways to mix and match references Refer to a derived-class object with a derived-class reference Refer to a base-class object with a base-class reference Refer to a derived-class object with a base-class reference (e.g. public class Circle : Point{} Point point; Circle circle; point = circle ) So a base-class reference cannot refer to derived-class-only members !!! 4. Refer to a base-class object with a derived-class reference – see a below: Point point; Circle circle; must first be cast to a derived-class reference as below otherwise syntax error Circle circle = (Circle) point;

18 Derived-Class-Object to Base-Class-Object Conversion
Store references to derived-class and base-class objects: Both straightforward Assign a derived-class reference to a derived-class-type variable (object) Assign a base-class reference to a base-class-type variable (object) Assign a derived-class reference variable to a base-class variable is safe and logical “is a” relationship: an object of a derived-class can be treated as an object of its base-class b/c the derived class contains all members of the base class

19 Type Fields and Switch Statements
Can be used to deal with many objects of different types Appropriate action based on object’s type e.g. in a hierarchy of shapes in which each shape object has a ShapeType property, a switch structure could employ the object’s ShapeType to determine which Print method to call. Problems using switch logic Programmer may forget to include a type Might forget to test all possible cases Every addition/deletion of a class requires all switch statements to be changed Tracking all these changes is time consuming and error prone How can we eliminate the need for switch logic Avoids all these problems automatically by providing polymorphism mechanism: switching between objects at run time

20 Dynamic Method Binding
Implements polymorphic processing of objects Use base-class reference to refer to derived-class object Program chooses “correct” method in derived class At execution time, method calls routed to appropriate method With polymorphism New classes can be added easily One method call can cause different actions to occur, depending on object receiving call

21 12.4 Abstract Classes and Methods
Cannot be instantiated Too generic to define real objects Used as base classes from which other classes may inherit (concrete classes) Incomplete derived-classes fill in "missing pieces“ Can contain abstract methods ([holders] and/or abstract properties Have no implementation Derived classes must override inherited abstract methods and properties to enable instantiation

22 12.4 Abstract Classes and Methods
Abstract classes not required, but reduce client code dependencies Can create references to abstract classes at compilation time Cannot instantiate objects of abstract classes abstract class and method – a common interface used by various members of a class hierarchy Declare with keyword abstract Contain one or more abstract methods with no implementation public abstract void draw(); public abstract class A { A() {} m1(){} m2(){} public abstract m3(){}} Any class with an abstract method must be abstract abstract methods must be overridden in derived class Otherwise, derived class must be abstract

23 12.4 Abstract Classes and Methods
Concrete classes Classes from which objects are instantiated Provide specifics for instantiating objects Square, Circle and Triangle use the keyword override to provide implementations for all the abstract methods and properties of the base-class Class hierarchies Most general classes are usually abstract Any class with an abstract method or property must be declared abstract Even though abstract classes cannot be instantiated, we can use abstract class references to refer to instances of any concrete class derived from the abstract class

24 Case Study: Inheriting Interface and Implementation
Shape hierarchy class diagram Circle Cylinder Point Shape

25 Case Study: Inheriting Interface and Implementation
Abstract base class Shape Concrete virtual method Area (default return value is 0) Concrete virtual method Volume (default return value is 0) Abstract read-only property Name Class Point2 inherits from Shape Overrides property Name (required) Does NOT override methods Area and Volume Class Circle2 inherits from Point2 Overrides property Name Overrides method Area, but not Volume Class Cylinder2 inherits from Circle2 Overrides methods Area and Volume

26 Case Study: Inheriting Interface and Implementation
abstract base-class Shape Abstract method (must be implemented) property Name, Default implementation does not make sense non-abstract methods Area (return 0) Volume (return 0.0) If not overridden, uses derived-class default implementation Shape <-Point <- Circle <- Cylinder hierarchy Polymorphism example uses an array of object references Class Shape used to define a set of common methods Interface is common methods: Area(), Volume()and property public abstract string Name; Implementation of Area and Volume used for first levels of hierarchy

27 Declaration of abstract class Shape
1 // Fig ed1: Shape.cs 2 // Demonstrate a shape hierarchy using an abstract base class. 3 using System; 4 5 public abstract class Shape 6 { // return Shape's area public virtual double Area() { return 0; } 12 // return Shape's volume public virtual double Volume() { return 0; } 18 // return Shape's name public abstract string Name { get; } 24 } Shape.cs Declaration of abstract class Shape Declaration of virtual methods Area and Volume with default implementations Declaration of read-only abstract property Name; implementing classes will have to provide an implementation for this property

28 Class Point2 inherits from class Shape
1 // Fig ed1: Point2.cs 2 // Point2 inherits from abstract class Shape and represents 3 // an x-y coordinate pair. 4 using System; 5 6 // Point2 inherits from abstract class Shape 7 public class Point2 : Shape 8 { private int x, y; // Point2 coordinates 10 // default constructor public Point2() { // implicit call to Object constructor occurs here } 16 // constructor public Point2( int xValue, int yValue ) { X = xValue; Y = yValue; } 23 // property X public int X { get { return x; } 31 set { x = value; // no validation needed } Point2.cs Class Point2 inherits from class Shape

29 Point2’s implementation of the read-only Name property
} 37 // property Y public int Y { get { return y; } 45 set { y = value; // no validation needed } } 51 // return string representation of Point2 object public override string ToString() { return "[" + X + ", " + Y + "]"; } 57 // implement abstract property Name of class Shape public override string Name { get { return "Point2"; } } 66 67 } // end class Point2 Point2.cs Point2’s implementation of the read-only Name property

30 Definition of class Circle2 which inherits from class Point2
1 // Fig ed1: Circle2.cs 2 // Circle2 inherits from class Point2 and overrides key members. 3 using System; 4 5 // Circle2 inherits from class Point2 6 public class Circle2 : Point2 7 { private double radius; // Circle2 radius 9 // default constructor public Circle2() { // implicit call to Point2 constructor occurs here } 15 // constructor public Circle2( int xValue, int yValue, double radiusValue ) : base( xValue, yValue ) { Radius = radiusValue; } 22 // property Radius public double Radius { get { return radius; } 30 Circle2.cs Definition of class Circle2 which inherits from class Point2

31 Override the Area method (defined in class Shape)
set { // ensure non-negative radius value if ( value >= 0 ) radius = value; } } 38 // calculate Circle2 diameter public double Diameter() { return Radius * 2; } 44 // calculate Circle2 circumference public double Circumference() { return Math.PI * Diameter(); } 50 // calculate Circle2 area public override double Area() { return Math.PI * Math.Pow( Radius, 2 ); } 56 // return string representation of Circle2 object public override string ToString() { return "Center = " + base.ToString() + "; Radius = " + Radius; } Circle2.cs Override the Area method (defined in class Shape)

32 Override the read-only Name property
63 // override property Name from class Point2 public override string Name { get { return "Circle2"; } } 72 73 } // end class Circle2 Override the read-only Name property Circle2.cs

33 Class Cylinder2 derives from Circle2
1 // Fig ed1: Cylinder2.cs 2 // Cylinder2 inherits from class Circle2 and overrides key members. 3 using System; 4 5 // Cylinder2 inherits from class Circle2 6 public class Cylinder2 : Circle2 7 { private double height; // Cylinder2 height 9 // default constructor public Cylinder2() { // implicit call to Circle2 constructor occurs here } 15 // constructor public Cylinder2( int xValue, int yValue, double radiusValue, double heightValue ) : base( xValue, yValue, radiusValue ) { Height = heightValue; } 22 // property Height public double Height { get { return height; } 30 set { // ensure non-negative height value if ( value >= 0 ) height = value; Cylinder2.cs Class Cylinder2 derives from Circle2

34 Override Area implementation of class Circle2 Cylinder2.cs
} } 38 // calculate Cylinder2 area public override double Area() { return 2 * base.Area() + base.Circumference() * Height; } 44 // calculate Cylinder2 volume public override double Volume() { return base.Area() * Height; } 50 // return string representation of Circle2 object public override string ToString() { return base.ToString() + "; Height = " + Height; } 56 // override property Name from class Circle2 public override string Name { get { return "Cylinder2"; } } 65 66 } // end class Cylinder2 Override Area implementation of class Circle2 Cylinder2.cs Override Volume implementation of class Shape Override read-only property Name

35 Create an array of Shape objects
1 // Fig ed1: AbstractShapesTest.cs 2 // Demonstrates polymorphism in Point-Circle-Cylinder hierarchy. 3 using System; 4 using System.Windows.Forms; 5 6 public class AbstractShapesTest 7 { public static void Main( string[] args ) { // instantiate Point2, Circle2 and Cylinder2 objects Point2 point = new Point2( 7, 11 ); Circle2 circle = new Circle2( 22, 8, 3.5 ); Cylinder2 cylinder = new Cylinder2( 10, 10, 3.3, 10 ); 14 // create empty array of Shape base-class references Shape[] arrayOfShapes = new Shape[ 3 ]; 17 // arrayOfShapes[ 0 ] refers to Point2 object arrayOfShapes[ 0 ] = point; //assign instance of derived class 20 // arrayOfShapes[ 1 ] refers to Circle2 object arrayOfShapes[ 1 ] = circle; 23 // arrayOfShapes[ 1 ] refers to Cylinder2 object arrayOfShapes[ 2 ] = cylinder; 26 string output = point.Name + ": " + point + "\n" + circle.Name + ": " + circle + "\n" + cylinder.Name + ": " + cylinder; 30 AbstractShapesTest.cs Create an array of Shape objects Assign a Shape reference to reference a Point2 object Assign a Shape reference to reference a Circle2 object Assign a Shape reference to reference a Cylinder2 object

36 AbstractShapesTest.cs Program Output
// display Name, Area and Volume for each object // in arrayOfShapes polymorphically foreach( Shape shape in arrayOfShapes ) { output += "\n\n" + shape.Name + ": " + shape + "\nArea = " + shape.Area().ToString( "F" ) + "\nVolume = " + shape.Volume().ToString( "F" ); } 39 MessageBox.Show( output, "Demonstrating Polymorphism" ); } 42 } Use a foreach loop to access every element of the array AbstractShapesTest.cs Program Output To verify all previous outputs: Rely on polymorphism to call the proper object’s methods (i.e. it maps each methods call to the proper object method)

37 Case Study: Inheriting Interface and Implementation
Dynamic binding (late binding) Accommodates new classes Object’s type need not be known at compile time At run time, method call matched with object Create an array of Shape references Point to various derived class objects Call methods using Shape reference

38 12.5 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

39 12.5 Case Study: Payroll System Using Polymorphism
Create a payroll program Use abstract methods and polymorphism Problem statement 4 types of employees, paid weekly Salaried (fixed salary, no matter the hours) Hourly (overtime [>40 hours] pays time and a half) Commission (paid percentage of sales) Base-plus-commission (base salary + percentage of sales) Boss wants to raise pay by 10% abstract base-class Employee has abstract method earnings Method earnings must be implemented in each employee’s subclasses Person’s earnings dependent on type of Employee Class EmployeeTest Initialize objects Use an Employee reference and call toString and earnings Through polymorphism, appropriate class method called

40 Definition of abstract class Employee
1 // Fig ed1: Employee.cs 2 // Abstract base class for company employees. 3 using System; 4 5 public abstract class Employee 6 { private string firstName; private string lastName; 9 // constructor public Employee( string firstNameValue, string lastNameValue ) { FirstName = firstNameValue; LastName = lastNameValue; } 17 // property FirstName public string FirstName { get { return firstName; } 25 set { firstName = value; } } 31 Employee.cs Definition of abstract class Employee

41 // property LastName public string LastName { get { return lastName; } 39 set { lastName = value; } } 45 // return string representation of Employee public override string ToString() { return FirstName + " " + LastName; } 51 // abstract method that must be implemented for each derived // class of Employee to calculate specific earnings public abstract decimal Earnings(); 55 56 } // end class Employee Employee.cs Declaration of abstract class Earnings – implementation must be provided by all derived classes

42 Definition of class Boss – derives from Employee Boss.cs
1 // Fig ed1: Boss.cs 2 // Boss class derived from Employee. 3 using System; 4 5 public class Boss : Employee 6 { private decimal salary; // Boss's salary 8 // constructor public Boss( string firstNameValue, string lastNameValue, decimal salaryValue) : base( firstNameValue, lastNameValue ) { WeeklySalary = salaryValue; } 16 // property WeeklySalary public decimal WeeklySalary { get { return salary; } 24 set { // ensure positive salary value if ( value > 0 ) salary = value; } } 32 Definition of class Boss – derives from Employee Boss.cs

43 33 // override base-class method to calculate Boss's earnings
public override decimal Earnings() { return WeeklySalary; } 38 // return string representation of Boss public override string ToString() { return "Boss: " + base.ToString(); } 44 } Implementation of method Earnings (required by classes deriving from Employee) Boss.cs

44 Definition of class CommissionWorker – derives from Employee
1 // Fig ed1: CommisionWorker.cs 2 // CommissionWorker class derived from Employee 3 using System; 4 5 public class CommissionWorker : Employee 6 { private decimal salary; // base weekly salary private decimal commission; // amount paid per item sold private int quantity; // total items sold 10 // constructor public CommissionWorker( string firstNameValue, string lastNameValue, decimal salaryValue, decimal commissionValue, int quantityValue ) : base( firstNameValue, lastNameValue ) { WeeklySalary = salaryValue; Commission = commissionValue; Quantity = quantityValue; } 21 // property WeeklySalary public decimal WeeklySalary { get { return salary; } 29 Definition of class CommissionWorker – derives from Employee CommisionWorker.cs

45 CommisionWorker.cs 30 set 31 { 32 // ensure non-negative salary value
{ // ensure non-negative salary value if ( value > 0 ) salary = value; } } 37 // property Commission public decimal Commission { get { return commission; } 45 set { // ensure non-negative commission value if ( value > 0 ) commission = value; } } 53 // property Quantity public int Quantity { get { return quantity; } 61 CommisionWorker.cs

46 set { // ensure non-negative quantity value if ( value > 0 ) quantity = value; } } 69 // override base-class method to calculate // CommissionWorker's earnings public override decimal Earnings() { return WeeklySalary + Commission * Quantity; } 76 // return string representation of CommissionWorker public override string ToString() { return "CommissionWorker: " + base.ToString(); } 82 83 } // end class CommissionWorker CommisionWorker.cs Implementation of method Earnings (required by classes deriving from Employee)

47 Definition of class PieceWorker – derives from Employee PieceWorker.cs
1 // Fig ed1: PieceWorker.cs 2 // PieceWorker class derived from Employee. 3 using System; 4 5 public class PieceWorker : Employee 6 { private decimal wagePerPiece; // wage per piece produced private int quantity; // quantity of pieces produced 9 // constructor public PieceWorker( string firstNameValue, string lastNameValue, decimal wagePerPieceValue, int quantityValue ) : base( firstNameValue, lastNameValue ) { WagePerPiece = wagePerPieceValue; Quantity = quantityValue; } 19 // property WagePerPiece public decimal WagePerPiece { get { return wagePerPiece; } 27 set { if ( value > 0 ) wagePerPiece = value; } } 34 Definition of class PieceWorker – derives from Employee PieceWorker.cs

48 // property Quantity public int Quantity { get { return quantity; } 42 set { if ( value > 0 ) quantity = value; } } 49 // override base-class method to calculate // PieceWorker's earnings public override decimal Earnings() { return Quantity * WagePerPiece; } 56 // return string representation of PieceWorker public override string ToString() { return "PieceWorker: " + base.ToString(); } 62 } PieceWorker.cs Implementation of method Earnings (required by classes deriving from Employee)

49 Definition of class HourlyWorker – derives from Employee
1 // Fig ed1: HourlyWorker.cs 2 // HourlyWorker class derived from Employee. 3 using System; 4 5 public class HourlyWorker : Employee 6 { private decimal wage; // wage per hour of work private double hoursWorked; // hours worked during week 9 // constructor public HourlyWorker( string firstNameValue, string LastNameValue, decimal wageValue, double hoursWorkedValue ) : base( firstNameValue, LastNameValue ) { Wage = wageValue; HoursWorked = hoursWorkedValue; } 18 // property Wage public decimal Wage { get { return wage; } 26 set { // ensure non-negative wage value if ( value > 0 ) wage = value; } } 34 Definition of class HourlyWorker – derives from Employee HourlyWorker.cs

50 35 // property HoursWorked
public double HoursWorked { get { return hoursWorked; } 42 set { // ensure non-negative hoursWorked value if ( value > 0 ) hoursWorked = value; } } 50 // override base-class method to calculate // HourlyWorker earnings public override decimal Earnings() { // compensate for overtime (paid "time-and-a-half") if ( HoursWorked <= 40 ) { return Wage * Convert.ToDecimal( HoursWorked ); } 60 else { // calculate base and overtime pay decimal basePay = Wage * Convert.ToDecimal( 40 ); decimal overtimePay = Wage * 1.5M * Convert.ToDecimal( HoursWorked - 40 ); 67 HourlyWorker.cs Implementation of method Earnings (required by classes deriving from Employee)

51 HourlyWorker.cs 68 return basePay + overtimePay; 69 } 70 } 71
} } 71 // return string representation of HourlyWorker public override string ToString() { return "HourlyWorker: " + base.ToString(); } 77 } HourlyWorker.cs

52 Assign Employee reference to reference a Boss object
1 // Fig ed1: EmployeesTest.cs 2 // Demonstrates polymorphism by displaying earnings 3 // for various Employee types. 4 using System; 5 using System.Windows.Forms; 6 7 public class EmployeesTest 8 { public static void Main( string[] args ) { Boss boss = new Boss( "John", "Smith", 800 ); 12 CommissionWorker commissionWorker = new CommissionWorker( "Sue", "Jones", 400, 3, 150 ); 15 PieceWorker pieceWorker = new PieceWorker( "Bob", "Lewis", Convert.ToDecimal( 2.5 ), 200 ); 18 HourlyWorker hourlyWorker = new HourlyWorker( "Karen", "Price", Convert.ToDecimal( ), 50 ); 21 Employee employee = boss; 23 string output = GetString( employee ) + boss + " earned " + boss.Earnings().ToString( "C" ) + "\n\n"; // it gives 2 the same output lines // "C“ = currency employee = commissionWorker; 28 output += GetString( employee ) + commissionWorker + " earned " + commissionWorker.Earnings().ToString( "C" ) + "\n\n"; 32 employee = pieceWorker; 34 EmployeesTest.cs Use method GetString() (below see local call) to polymorphically obtain salary information. Then use the original Boss reference to obtain the information Assign Employee reference to reference a Boss object

53 EmployeesTest.cs Program Output
output += GetString( employee ) + pieceWorker + " earned " + pieceWorker.Earnings().ToString( "C" ) + "\n\n"; 38 employee = hourlyWorker; 40 output += GetString( employee ) + hourlyWorker + " earned " + hourlyWorker.Earnings().ToString( "C" ) + "\n\n"; 44 MessageBox.Show( output, "Demonstrating Polymorphism", MessageBoxButtons.OK, MessageBoxIcon.Information ); 47 } // end method Main 49 // return string that contains Employee information public static string GetString( Employee worker ) { return worker.ToString() + " earned " + // polymorphic call worker.Earnings().ToString( "C" ) + "\n"; // ToString( "C" ) converts from //decimal earnings into a currency amount } 56 } EmployeesTest.cs Program Output Definition of method GetString, which takes as an argument an Employee object and gives the 1st line output for each of 4 workers. To verify all previous outputs Polymorphically call the method ToString() and Earnings() of the appropriate derived class Output: The 1st line in each group shows that the polymorphic methods invoke the appropriate methods in derived objects

54 Fig. 12.2 | Employee hierarchy UML class diagram - last 5th edition
= Employee (ed4) = Boss (ed4) = HourlyWorker (ed4) <= 2nd level = CommissionWorker (ed4) Compare with the previous example: SalariedEmployee = Boss (ed4) BasePlusCommissionEmployee = CommissionWorker (ed4) HourlyEmployee = HourlyWorker (ed4)

55 Fig. 12.3 | Polymorphic interface for the Employee hierarchy classes.
= Boss(ed4) = HourlyWorker (ed4) = CommissionWorker (ed4) = Boss (ed4) = HourlyWorker (ed4) = CommissionWorker (ed4)

56 Outline Employee.cs (1 of 2)

57 Outline Employee.cs (2 of 2)

58 Outline SalariedEmployee.cs (1 of 2)

59 Outline SalariedEmployee .cs (2 of 2)

60 Outline HourlyEmployee.cs (1 of 3)

61 Outline HourlyEmployee.cs (2 of 3)

62 Outline HourlyEmployee.cs (3 of 3)

63 Outline CommissionEmployee.cs (1 of 2)

64 Outline CommissionEmployee.cs (2 of 2)

65 Outline BasePlusCommissionEmployee.cs (1 of 2)

66 Outline BasePlusCommissionEmployee.cs (2 of 2)

67 PayrollSystemTest.cs (1 of 5) Outline

68 Outline PayrollSystemTest.cs (2 of 5)

69 Outline PayrollSystemTest.cs (3 of 5)


Download ppt " 2002 Prentice Hall. All rights reserved."

Similar presentations


Ads by Google