Presentation is loading. Please wait.

Presentation is loading. Please wait.

Polymorphism, Interfaces &

Similar presentations


Presentation on theme: "Polymorphism, Interfaces &"— Presentation transcript:

1 Polymorphism, Interfaces &
Chapter 12 Polymorphism, Interfaces & Operator Overloading Many slides modified by Prof. L. Lilien (even many without explicit message). Slides added by L.Lilien are © Leszek T. Lilien. Permision to use for non-commercial purposes slides added by L.Lilien’s will be gladly granted upon a written (e.g., ed) request.

2 12.2 Polymorphism Examples 12.3 Demonstrating Polymorphic Behavior
12.1   Introduction [10.2 in ed.1] Derived-Class-Object to Base-Class-Object Conversion [10.3 in ed.1] Type Fields and switch Statements 12.2   Polymorphism Examples 12.3   Demonstrating Polymorphic Behavior 12.4   Abstract Classes and Methods [10.6 in ed.1] Case Study: Inheriting from an Abstract Class and Implementation 12.5   Case Study: Inheriting from an Abstract Class (Optional) Case Study: Payroll System Using Polymorphism 12.6   sealed Methods and Classes 12.7   Case Study: Creating and Using Interfaces [10.10 in ed.1] Delegates 12.8   Operator Overloading 12.9   (Optional) Software Engineering Case Study: Incorporating Inheritance and Polymorphism into the ATM System

3 12.1. Introduction Polymorphism Examples – next slide
Poly = many , morph = form Polymorphic = having many forms Examples – next slide

4 12.2. Polymorphism Examples
Quadrilateral base-class contains method CalcPerimeter Rectangle derived-class implements CalcPerimeter Trapezoid derived-class implements CalcPerimeter Quadrilateral Rectangle Trapezoid Object (namespace: System) implicit inheritance explicit inheritance Figure added by L. Lilien

5 12.2. Polymorphism Examples (Cont.)
Base class: Quadrilateral Derived classes: Rectangle, Trapezoid Polymorhpic “Quadrilateral.CalcPerimeter” method 2 (“many”) forms of CalcPerimeter For 2classes derived from Quadrilateral “Quadrilateral.CalcPerimeter” morphs (re-forms, reshapes) to fit the class of the object for which it is called Becomes Rectangle.CalcPerimeter for a Rectangle object Becomes Trapezoid.CalcPerimeter for a Trapezoid object -- see next slide -- Slide modified by L. Lilien

6 12.2. Polymorphism Examples (Cont.)
Example 1 – cont. Populate (polymorphic) array with objects of different base and derived classes Quadrilateral[] quadrilatArray = new Quadrilateral[20]; quadrilatArray[0] = new Quadrilateral( … ); quadrilatArray[1] = new Trapezoid( … ); quadrilatArray[2] = new Rectangle( … ); quadrilatArray[3] = new Quadrilateral( … ); quadrilatArray[4] = new Rectangle( … ); quadrilatArray[5] = new Rectangle( … ); quadrilatArray[6] = new Trapezoid( … ); quadrilatArray[7] = new Trapezoid( … ); Slide added by L. Lilien

7 12.2. Polymorphism Examples (Cont.)
Example 1 – cont. Loop (polymorphically) handles objects of different base & derived classes foreach ( Quadrilateral quadrilat in quadrilatArray ) { quadrilat.CalcPerimeter( … ); // morphs (re-forms, reshapes) to fit the class // of the object for which it is called: // becomes Rectangle.CalcPerimeter when // quadrilat refers (points) to a Rectangle // object, and // becomes Trapezoid.CalcPerimeter when // quadrilat refers (points) to a Trapezoid // object } Slide added by L. Lilien

8 12.2. Polymorphism Examples (Cont.)
IMPORTANT: Make sure that you understand the previous example fully: In a method call, the type of the actual referenced object, not the type of the reference, determines which method is called Another (Simplified) Example: Example 1b Object hierarchy: base class Quadrilateral derived class Rectangle Program P includes this code: Rectangle rectangle1 = new Rectangle(<params>); Quadrilateral quad1 = rectangle1; … quad1.CalcPerimeter … // type of the reference (quad1) is Quadrilateral // type of the actual referenced object is // Rectangle (bec. quad1 references Rectangle)

9 12.2. Polymorphism Examples (Cont.)
Example 2 (similar to Example 1 but for any code, not just for a loop): Quadrilateral base-class contains method CalcPerimeter Rectangle derived-class implements CalcPerimeter Square second-level derived-class implements CalcPerimeter Parallelogram derived-class implements CalcPerimeter Trapezoid derived-class implements CalcPerimeter Quadrilateral Square Parallelogram Rectangle Trapezoid Object (namespace: System) implicit inheritance explicit inheritance Figure added by L. Lilien

10 12.2. Polymorphism Examples (Cont.)
Operation CalcPerimeter that can be performed on a Quadrilateral object, can also be performed on derived objects Rectangle, Square, Parallelogram, or Trapezoid Example: [added by L. Lilien] Program P instantiated a Rectangle/ Square/… object referenced via rectangle1/square1/…: Rectangle rectangle1 = new Rectangle (…); Square square1 = new Square (…); P can use a base-class reference quad1 to invoke derived-class methods Rectangle.CalcPerimeter, Square.CalcPerimeter, … Quadrilateral quad1 = rectangle1; … quad1.CalcPerimeter … // CalcPerimeter executed // on the derived-class object rectangle1 via the // base-class reference quad1.perimeter Quadrilateral quad1 = square1; … quad1.CalcPerimeter … // CalcPerimeter is executed // on the derived-class object square1 via the // same base-class reference quad1.perimeter With such a (polymorhic) Quadrilateral reference, C# polymorphically chooses the correct overriding method in any of these derived-classes from which the object is instantiated Slide modified by L. Lilien

11 ++READ LATER++ 12.2. Polymorphism Examples (Cont.)
Example 3 (again, very similar to Example 1): 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) SpaceObject Martian Plutonian Venutian SpaceShip Object (namespace: System) implicit inheritance explicit inheritance Figure added by L. Lilien

12 ++READ LATER++ 12.2. Polymorphism Examples (Cont.)
A screen-manager program may contain an array of references to SpaceObject objects of various classes derived from SpaceObject arrOfSpaceObjects[ 0 ] = martian1; arrOfSpaceObjects[ 1 ] = martian2; arrOfSpaceObjects[ 2 ] = venutian1; arrOfSpaceObjects[ 3 ] = plutonian1; arrOfSpaceObjects[ 4 ] = spaceShip1; To refresh the screen, the screen-manager calls DrawYourself on each object in the array foreach(SpaceObject spaceObject in arrOfSpaceObjects) { spaceObject.DrawYourself } The program polymorphically calls the appropriate version of DrawYourself on each object, based on the type of that object Listing added by L. Lilien Listing added by L. Lilien

13 12.2 Polymorphism Examples (Cont.)
Polymorphism allows: Programs that handle a wide variety of related classes in a generic manner Programs that are easily extensible

14 ++READ LATER++ 12.2 Polymorphism Examples (Cont.)
Software Engineering Observation 12.1 Polymorphism promotes extensibility: Software that invokes polymorphic behavior is independent of the object types to which messages are sent. Only client code that instantiates new objects must be modified to accommodate new types.

15 12.3 Demonstrating Polymorphic Behavior
RECALL: In a method call on an object, the type of the actual referenced object, not the type of the reference, determines which method is called An object of a derived class can be treated as an object of its base class Because object of a derived class is-a(n) object of its base class E.g., car is-a vehicle (every car is a vehicle) A base-class object is not an object of any of its derived classes E.g. , not every vehicle is not a car (vehicle can be a plane) The is-a relationship applies from a derived class to its direct and indirect base classes, but not vice versa.

16 12. 3 Demonstrating Polymorphic Behavior (Cont
12.3  Demonstrating Polymorphic Behavior (Cont.) Derived-Class-Object to Base-Class-Object Conversion Class hierarchies Can explicitly cast between types in a class hierarchy (next) Can assign derived-class objects to base-class references - A fundamental part of programs that process objects polymorphically This means that: An object of a derived-class can be treated as an object of its base-class (The reverse is NOT true, i.e.: base-class object can not be treated as an object of any of its derived classes) That is why we can have arrays of base-class references that refer to objects of many derived-class types (as shown in examples above) Slide modified by L. Lilien

17 12. 3 Demonstrating Polymorphic Behavior (Cont
12.3  Demonstrating Polymorphic Behavior (Cont.) Casting: Downcasting and Upcasting Casting = taking a reference to a base/derived class and transforming it to a reference to a derived/base , respectively, class 2 kinds of casting in C#: 1) Upcasting (can be implicit): Transforming a reference to a base class to a reference to a derived class I.e., a reference to an object of a derived class assigned to a variable declared as a reference to an object of its base class (Example 1 below) 2) Downcasting (must be explicit): Transforming a reference to a derived class to a reference to a base class I.e. a reference to an object of a base class is assigned to a variable declared as a reference to an object of its derived class 2a) Downcasting is correct only if it is explicit and the base-class reference variable actually refers to ("points to") a derived-class object (Example 2 below) 2b) Downcasting is incorrect if the base-class reference variable actually refers ("points to") to a base-class object (Example 3 below) Slided added by L. Lilien

18 12. 3 Demonstrating Polymorphic Behavior (Cont
12.3  Demonstrating Polymorphic Behavior (Cont.) Downcasting and Upcasting Examples Assume the Point-Circle object hierarchy for all 3 examples below Example 1: Implicit upcasting (assigning a derived-class reference to a variable of a base-class type) Circle circle10 = new Circle( 120, 89, 2.7 ); // "Circle circle10" declares circle10 as a reference to // an object of the derived class Circle. // After the assignment, circle10 points to the just-created // derived-class object (of class Circle) Point point22 = circle10; // "Point point22" declares point22 as a reference to // an object of the base class Point. // However, after the assignment with an (implicit) upcast, // point22 actually points to the object (also pointed to // by circle10) of the derived-class type Circle. Slided added by L. Lilien

19 12. 3 Demonstrating Polymorphic Behavior (Cont
12.3  Demonstrating Polymorphic Behavior (Cont.) Downcasting and Upcasting Examples (Cont.) Examples 2a and 2b are for correct and incorrect downcasting, resp. Downcasting = assigning a base-class reference to a variable of a derived-class type Example 2a: Correct explicit downcasting (assigning a base-class reference –actually pointing to a derived-class object-- to a variable of a derived-class type) Circle circle10 = new Circle( 120, 89, 2.7 ); // "Circle circle10" declares circle10 as a reference to // an object of the derived class Circle. // After the assignment, circle10 points to the just-created // derived-class object (of class Circle). Point point22 = circle10; // "Point point22" declares point22 as a reference to // an object of the base class Point. // However, after the assignment, point22 actually points to // an object (also pointed to by circle10) of the derived // class Circle. Circle circle20 = ( Circle ) point22; // Now, the _explicit_ downcast assigned a base-class reference // (point22), actually pointing to a derived-class object // (circle10), to a derived-class reference (circle20). Slided added by L. Lilien

20 12. 3 Demonstrating Polymorphic Behavior (Cont
12.3  Demonstrating Polymorphic Behavior (Cont.) Downcasting and Upcasting Examples (Cont.) RECALL: Examples 2a and 2b are for correct and incorrect downcasting, resp. Downcasting = assigning a base-class reference to a variable of a derived-class type Example 2b: Incorrect explicit downcasting (trying to assign a base-class reference—actually pointing to a base-class object-- to a variable of a derived-class type) Point point10 = new Point( 30, 50 ); // "Point point10" declares point10 as a reference to // an object of the base class Point. // After the assignment, point10 actually points to circle30 = ( Circle ) point10; // Incorrect downcast! Objects may only be cast to // their own class or downcast to their base class // (bec. a derived class IS-A a base class, e.g., // Circle IS-A Point). // Here, point10’s own class is Point, and Circle is // not a base class for Point (not true that // Point IS-A Circle). Slided added by L. Lilien

21 ++READ LATER++ |12. 3 Demonstrating Polymorphic Behavior (Cont
++READ LATER++ |12.3  Demonstrating Polymorphic Behavior (Cont.) Casting: Downcasting and Upcasting (Cont.) The compiler allows the assignment of a base-class reference to a derived-class variable only if we explicitly downcast the base-class reference to the derived-class type. If an application needs to perform a derived-class-specific operation on a derived-class object referenced by a base-class variable, the base-class reference must be explicitly downcast to a derived-class reference Slided added by L. Lilien

22 Definition of class Point
1 // Fig. 10.1: Point.cs [in textbook ed.1] 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

23 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

24 Definition of class Circle which inherits from class Point
1 // Fig. 10.2: Circle.cs [in textbook ed.1] 2 // Circle class that inherits from class Point. 3 4 using System; 5 6 // Circle class definition inherits from Point 7 public class Circle : Point 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

25 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

26 Point point1 (object itself)
1 // Fig. 10.3: PointCircleTest.cs [in textbook ed.1] 2 // Demonstrating inheritance and polymorphism. 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 ) { Point point1 = new Point( 30, 50 ); 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 // Circle circle1 to Point reference Point point2 = circle1; 22 output += "\n\nCCircle circle1 (via point2): " + point2.ToString(); // Circle’s ToString called, not Point’s // ToString, since point2 references now a Circle object (circle1). // (Object type determines method version, not reference type.) 25 // downcast (cast base-class reference to derived-class // data type) point2 to Circle circle2 Circle circle2 = ( Circle ) point2; 29 output += "\n\nCircle circle1 (via circle2 [and point2]): " + circle2.ToString(); 32 output += "\nArea of circle1 (via circle2): " + circle2.Area().ToString( "F" ); 35 Create a Point object PointCircleTest.cs Upcast: Assign Circle circle1 (derived-class object) to Point point2 reference (base-class object reference) - OK since Circle is-a Point Create a Circle object Use base-class reference to access a derived-class object Downcasts Point object point2 (which references a Circle object circle1) to a Circle and then assigns the result to the Circle reference circle2. (Downcast would be dangerous if point2 were referencing a Point! It is OK since point2 references a Circle) Circle circle1 (object itself) point2 a reference circle 1 Point point1 (object itself) point circle2 Slide modified by L. Lilien

27 Point point1 (object itself)
// attempt to assign point1 object to Circle reference if ( point1 is Circle ) { circle2 = ( Circle ) point1; // Incorrect! Objects may be // cast only to their own type, or downcast to their // base-class types. (bec. derived class IS-A base class, // e.g., Circle IS-A Point!). Here, point1’s own type is // Point, and Circle is not a base-class type for Point // (not true that Point IS-A Circle). 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 Test (using “is”) if point1 references a Circle object – it does not since point1 references a Point object ( l.13) PointCircleTest.cs Circle circle1 (object itself) point2 a reference Circle 1 Point point1 (object itself) Point circle2 Slide modified by L. Lilien

28 Notes on PointCircleTest (p. 387-ed.1):
NOTE: All pages – textbook ed.1 Object (namespace: System) Point – p. 384-ed.1 Slide added by L. Lilien implicit inheritance explicit inheritance Circle – p. 385-ed.1 Notes on PointCircleTest (p. 387-ed.1): l.21: Point point2 = circle1; - upcast: uses 'is a' relationship to assign Circle circle1 (derived-class object) to Point point2 reference (base-class object reference). l.24: point2.ToString(); - Circle’s ToString() method called, not Point’s ToString(), since point2 references at that point a Circle object (circle1). Recall: Object type, not reference type, determines method version. This is another example of polymorphism. 3) l.28: Circle circle 2 = (Circle) point2; – downcasts Point object point2 (which references a Circle object circle1) to a Circle and then assigns the result to the Circle reference circle2. Downcast would be dangerous if point2 were referencing a Point! (but it references a Circle – see l.21) l.37: if ( point1 is Circle ) - tests (using “is”) if the object referenced by point1 is-a Circle (i.e., is an object of the Circle class) l.37: circle2 = ( Circle ) point1; - Incorrect cast attempt! Objects may be cast only to their own type ,or downcast to the base-class types. Here, point1’s own type is Point, and Circle is not a base-class type for Point. Line 37 would cause an execution error if it were executed. But this line is never executed (do you know why?). Slide added by L. Lilien

29 Point point1 (object itself) point1
Circle circle1 (object itself) circle1 point2 circle2 a reference Slide added by L. Lilien

30 ++READ LATER++ 12.3 Demonstrating Polymorphic Behavior (Cont.)
When the compiler encounters a method call made through a variable, it determines if the method can be called by checking the variable’s class type. At execution time, the type of the object to which the variable refers determines the actual method to use.

31 12.4. Abstract Classes and Methods
Cannot be instantiated Are 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 abstract properties to enable instantiation Abstract methods and abstract properties are implicitly virtual (citing from ed.1, p.395/1) Slide modified by L. Lilien

32 12.4. Abstract Classes and Methods (Cont.)
To define an abstract class, use keyword abstract in the declaration To declare an abstract method or property, use keyword abstract in the declaration Any class with at least one abstract method or property must be declared abstract

33 12.4. Abstract Classes and Methods (Cont.)
Abstract classes can not be instantiated (used for creating, by instantiation, real objects) They are too generic , too abstract Instead, abstract classes are used to provide appropriate base classes Till this lecture, we considered only concrete classes We called them “classes “ (not “concrete classes”) A concrete class may inherit from an abstract base class Concrete classes can (of course!) be instantiated

34 12.4. Abstract Classes and Methods (Cont.)
Concrete classes use the keyword override to provide implementations for all the abstract methods and properties of the base-class Abstract classes are very useful, even though they can not be instantiated: We can use abstract class references to refer to instances of any concrete class derived from the abstract class We can use abstract base classes to declare variables that can hold references to objects of any concrete classes derived from those abstract classes You can use such variables to manipulate derived-class objects polymorphically and to invoke static methods declared in those abstract base classes

35 12.4 Abstract Classes and Methods (Cont.)
Abstract property declarations have the form: public abstract PropertyType MyProperty { get; set; } // end abstract property An abstract property may omit implementations for the get accessor, the set accessor or both (as shown above)

36 12.4 Abstract Classes and Methods (Cont.)
Constructors and static methods can not be declared abstract. ++READ LATER++ Software Engineering Observation 12.2 An abstract class declares common attributes and behaviors of the various classes that inherit from it, either directly or indirectly, in a class hierarchy. An abstract class typically contains one or more abstract methods or properties that concrete derived classes must override.

37 ++READ LATER++ 12.4 Abstract Classes and Methods (Cont.)
Common Programming Error 12.1 Attempting to instantiate an object of an abstract class is a compilation error. Common Programming Error 12.2 Failure to implement a base class’s abstract methods and properties in a derived class is a compilation error unless the derived class is also declared abstract.

38 12. 5. Case Study: Inheriting from an Abstract Class [see Fig
12.5. Case Study: Inheriting from an Abstract Class [see Fig. - next slide] [Sec in textbook ed.1] 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 abstract property Name (required) Does NOT override methods Area and Volume Area = 0 and Volume =0 are correct for a point Class Circle2 inherits from Point2 Overrides property Name Overrides method Area, but not Volume Volume =0 is correct for a circle Class Cylinder2 inherits from Circle2 Overrides methods Area and Volume

39 NOTE: All pages – textbook ed.1
Object (namespace: System) implicit inheritance explicit inheritance abstract class Shape (p.394) Concrete virtual method Area Concrete virtual method Volume Abstract read-only property Name class Point2 (p.395) Overrides abstract property Name Does not override methods Area and Volume (default return values Area = 0 and Volume =0 are correct for a point) class Circle2 (p.397) Overrides property Name Overrides method Area, but not Volume (Volume =0 is correct for a circle) class Cylinder2 (p.398) Overrides property Name Overrides methods Area and Volume Slide added by L. Lilien

40 Declaration of abstract class Shape
1 // Fig. 10.4: Shape.cs [in textbook ed.1] 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 } Declaration of virtual methods Area and Volume with default implementations Shape.cs Declaration of abstract class Shape Declaration of read-only (get) abstract property Name; implementing classes will have to provide an implementation for this property

41 Class Point2 inherits from class Shape
1 // Fig. 10.5: Point2.cs [in textbook ed.1] 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

42 Point2’s implementation of the read-only Name property Point2.cs
} 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’s implementation of the read-only Name property Point2.cs

43 Definition of class Circle2 which inherits from class Point2
1 // Fig. 10.6: Circle2.cs [in textbook ed.1] 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

44 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)

45 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

46 Class Cylinder2 derives from Circle2
1 // Fig. 10.7: Cylinder2.cs [in textbook ed.1] 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

47 Override read-only property Name
} } 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 read-only property Name Cylinder2.cs Override Area implementation of class Circle2 Override Volume implementation of class Shape

48 Assign a Shape reference to reference a Point2 object
1 // Fig. 10.8: AbstractShapesTest.cs [in textbook ed.1] 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; 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 Assign a Shape reference to reference a Point2 object AbstractShapesTest.cs Create an array of Shape objects Assign a Shape reference to reference a Cylinder2 object Assign a Shape reference to reference a Circle2 object Slide modified by L. Lilien

49 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 Rely on polymorphism to call appropriate version of methods

50 ++READ LATER++ 12.5 Case Study: …(Cont.)
Software Engineering Observation 12.3 A derived class can inherit “interface” or “implementation” from a base class. Hierarchies designed for implementation inheritance tend to have their functionality high in the hierarchy. Hierarchies designed for interface inheritance tend to have their functionality lower in the hierarchy.

51 ** OPTIONAL ** 12.5-B Case Study: Payroll System Using Polymorphism
Create an enhanced employee hierarchy to solve the following problem: A company pays its employees on a weekly basis. The employees are of four types: salaried employees are paid a fixed weekly salary regardless of the number of hours worked, hourly employees are paid by the hour and receive overtime pay for all hours worked in excess of 40 hours, commission employees are paid a percentage of their sales, salaried-commission employees receive a base salary plus a percentage of their sales. For the current pay period, the company has decided to reward salaried-commission employees by adding 10% to their base salaries.

52 ** OPTIONAL ** 12.5  Case Study: Payroll System Using Polymorphism (Cont.)
We use abstract class Employee to represent the general concept of an employee. SalariedEmployee, CommissionEmployee and HourlyEmployee extend Employee. Class BasePlusCommissionEmployee—which extends CommissionEmployee—represents the last employee type.

53 Fig. 12.2 | Employee hierarchy UML class diagram
** OPTIONAL ** 12.5  Case Study: Payroll System Using Polymorphism (Cont.) The UML class diagram in Fig. 12.2 shows the inheritance hierarchy for our polymorphic employee payroll application. Fig | Employee hierarchy UML class diagram

54 [REPETAED] Software Engineering Observation 12.3
** OPTIONAL ** 12.5  Case Study: Payroll System Using Polymorphism (Cont.) [REPETAED] Software Engineering Observation 12.3 A derived class can inherit “interface” or “implementation” from a base class. Hierarchies designed for implementation inheritance tend to have their functionality high in the hierarchy. Hierarchies designed for interface inheritance tend to have their functionality lower in the hierarchy.

55 12.5.1 Creating Abstract Base Class Employee
** OPTIONAL ** 12.5  Case Study: Payroll System Using Polymorphism (Cont.) Creating Abstract Base Class Employee Class Employee provides methods Earnings and ToString, in addition to the properties that manipulate Employee’s instance variables. Each earnings calculation depends on the employee’s class, so we declare Earnings as abstract. The application iterates through the array and calls method Earnings for each Employee object. C# processes these method calls polymorphically. Each derived class overrides method ToString to create a string representation of an object of that class.

56 Fig. 12.3 | Polymorphic interface for the Employee hierarchy classes.
** OPTIONAL ** 12.5  Case Study: Payroll System Using Polymorphism (Cont.) The diagram in Fig. 12.3 shows each of the five classes in the hierarchy down the left side and methods Earnings and ToString across the top. Fig | Polymorphic interface for the Employee hierarchy classes.

57 ** OPTIONAL ** The Employee class’s declaration is shown in Fig. 12.4.
Outline The Employee class’s declaration is shown in Fig. 12.4. Employee.cs (1 of 2 ) Fig | Employee abstract base class. (Part 1 of 2.)

58 Fig. 12.4 | Employee abstract base class. (Part 2 of 2.)
** OPTIONAL ** Outline Employee.cs (1 of 2 ) The Employee class includes an abstract method Earnings, which must be implemented by concrete derived classes. Fig | Employee abstract base class. (Part 2 of 2.)

59 SalariedEmployee extends Employee.
** OPTIONAL ** Outline SalariedEmployee .cs (1 of 2 ) SalariedEmployee extends Employee. Using the base class constructor to initialize the private variables not inherited from the base class. Fig | SalariedEmployee class that extends Employee. (Part 1 of 2.)

60 Method ToString overrides Employee method ToString.
** OPTIONAL ** Outline SalariedEmployee .cs (2 of 2 ) Method Earnings overrides Employee’s abstract method Earnings to provide a concrete implementation that returns the SalariedEmployee’s weekly salary. Method ToString overrides Employee method ToString. Fig | SalariedEmployee class that extends Employee. (Part 2 of 2.)

61 ** OPTIONAL ** Outline Class HourlyEmployee (Fig. 12.6) also extends class Employee. HourlyEmployee.cs (1 of 3 ) Fig | HourlyEmployee class that extends Employee. (Part 1 of 3.)

62 ** OPTIONAL ** Outline HourlyEmployee.cs (2 of 3 ) Method ToString overrides Employee method ToString. The set accessor in property Hours ensures that hours is in the range 0–168 (the number of hours in a week). Fig | HourlyEmployee class that extends Employee. (Part 2 of 3.)

63 Fig. 12.6 | HourlyEmployee class that extends Employee. (Part 3 of 3.)
** OPTIONAL ** Outline HourlyEmployee.cs (3 of 3 ) Fig | HourlyEmployee class that extends Employee. (Part 3 of 3.)

64 CommissionEmployee .cs
** OPTIONAL ** Outline Class CommissionEmployee (Fig. 12.7) extends class Employee. CommissionEmployee .cs (1 of 3 ) Fig | CommissionEmployee class that extends Employee. (Part 1 of 3.)

65 CommissionEmployee .cs
** OPTIONAL ** Outline CommissionEmployee .cs (2 of 3 ) Fig | CommissionEmployee class that extends Employee. (Part 2 of 3.)

66 CommissionEmployee .cs
** OPTIONAL ** Outline CommissionEmployee .cs (3 of 3 ) Calling base-class method ToString to obtain the Employee-specific information. Fig | CommissionEmployee class that extends Employee. (Part 3 of 3.)

67 BasePlusCommission Employee.cs
** OPTIONAL ** Outline Class BasePlusCommissionEmployee (Fig. 12.8) extends class Commission­Employee and therefore is an indirect derived class of class Employee. BasePlusCommission Employee.cs (1 of 2 ) Fig | BasePlusCommissionEmployee class that extends CommissionEmployee. (Part 1 of 2.)

68 BasePlusCommission Employee.cs
** OPTIONAL ** Outline BasePlusCommission Employee.cs (2 of 2 ) Method Earnings calls the base class’s Earnings method to calculate the commission-based portion of the employee’s earnings. BasePlusCommissionEmployee’s ToString method creates a string that contains "base-salaried", followed by the string obtained by invoking base class CommissionEmployee’s ToString method (a good example of code reuse) then the base salary. Fig | BasePlusCommissionEmployee class that extends CommissionEmployee. (Part 2 of 2.)

69 ** OPTIONAL ** Outline The application in Fig. 12.9 tests our Employee hierarchy. PayrollSystemTest .cs (1 of 6 ) Create objects of each of the four concrete Employee derived classes. Fig | Employee hierarchy test application. (Part 1 of 6.)

70 ** OPTIONAL ** Outline PayrollSystemTest .cs (2 of 6 ) Each object’s ToString method is called implicitly. Fig | Employee hierarchy test application. (Part 2 of 6.)

71 Fig. 12.9 | Employee hierarchy test application. (Part 3 of 6.)
** OPTIONAL ** Outline PayrollSystemTest .cs (2 of 6 ) Method calls are resolved at execution time, based on the type of the object referenced by the variable. The is operator is used to determine whether a particular Employee object’s type is BasePlusCommissionEmployee. Downcasting current­Employee from type Employee to type BasePlusCommissionEmployee. Fig | Employee hierarchy test application. (Part 3 of 6.)

72 Fig. 12.9 | Employee hierarchy test application. (Part 4 of 6.)
** OPTIONAL ** Outline PayrollSystemTest .cs (3 of 6 ) Method calls are resolved at execution time, based on the type of the object referenced by the variable. Method GetType returns an object of class Type, which contains information about the object’s type. Fig | Employee hierarchy test application. (Part 4 of 6.)

73 Fig. 12.9 | Employee hierarchy test application. (Part 5 of 6.)
** OPTIONAL ** Outline PayrollSystemTest .cs (5 of 6 ) Fig | Employee hierarchy test application. (Part 5 of 6.)

74 Fig. 12.9 | Employee hierarchy test application. (Part 6 of 6.)
** OPTIONAL ** Outline PayrollSystemTest .cs (6 of 6 ) Fig | Employee hierarchy test application. (Part 6 of 6.)

75 ++READ LATER++ 12.5  Case Study: Payroll System Using Polymorphism (Cont.)
Common Programming Error 12.3 Assigning a base-class variable to a derived-class variable (without an explicit downcast) is a compilation error. Software Engineering Observation 12.4 If at execution time the reference to a derived-class object has been assigned to a variable of one of its direct or indirect base classes, it is acceptable to cast the reference stored in that base-class variable back to a reference of the derived-class type. Before performing such a cast, use the is operator to ensure that the object is indeed an object of an appropriate derived-class type.

76 Common Programming Error 12.4
++READ LATER   Case Study: Payroll System Using Polymorphism (Cont.) Common Programming Error 12.4 When downcasting an object, an InvalidCastException (of namespace System) occurs if at execution time the object does not have an is-a relationship with the type specified in the cast operator. An object can be cast only to its own type or to the type of one of its base classes.

77 The Type class’s ToString method returns the class name.
** OPTIONAL ** 12.5  Case Study: Payroll System Using Polymorphism (Cont.) You can avoid a potential InvalidCastException by using the as operator to perform a downcast rather than a cast operator. If the downcast is invalid, the expression will be null instead of throwing an exception. Method GetType returns an object of class Type (of namespace System), which contains information about the object’s type, including its class name, the names of its methods, and the name of its base class. The Type class’s ToString method returns the class name.

78 ** OPTIONAL ** 12.5  Case Study: Payroll System Using Polymorphism (Cont.)
12.5.7 Summary of the Allowed Assignments Between Base-Class and Derived-Class Variables Assigning a base-class reference to a base-class variable is straightforward. Assigning a derived-class reference to a derived-class variable is straightfor­ward. Assigning a derived-class reference to a base-class variable is safe, because the derived-class object is an object of its base class. However, this reference can be used to refer only to base-class members. Attempting to assign a base-class reference to a derived-class variable is a compilation error. To avoid this error, the base-class reference must be cast to a derived-class type explicitly.

79 12.6. sealed Methods and Classes
sealed is a keyword in C# sealed methods and sealed classes 1)sealed methods cannot be overridden in a derived class Methods declared static or private are implicitly sealed 2)sealed classes cannot have any derived-classes Creating sealed classes can allow some runtime optimizations E.g., virtual method calls can be transformed into non-virtual method calls Slide modified by L. Lilien

80 12.7. Case Study: Creating and Using Interfaces
Interfaces are used to “bring together” or relate to each other disparate objects that relate to one another only through the interface I.e., provide uniform set of methods and properties for disparate objects E.g.: A person, a tree a car, …, are disparate objects An interface to define age and name for these disparate objects: public interface IAge { int Age { get; } string Name { get; } } Enables polymorphic processing of age and name for these disparate objects Slide modified by L. Lilien

81 Case Study: Creating and Using Interfaces – Cont.
Interfaces specify the public services (methods and properties) that classes must implement Interfaces vs. abstract classes w.r.t default implementations: Interfaces provide no default implementations Abstract classes may provide some default implementations => If no default implementations can/are defined, do not use an abstract class, use an interface instead Slide modified by L. Lilien

82 12.7. Case Study: Creating and Using Interfaces (Cont.)
Interfaces are defined using keyword interface Use inheritance notation to specify that a class implements an interface ClassName : InterfaceName Classes may implement more then one interface: e.g.: ClassName : InterfaceName1, InterfaceName2 Can also have: ClassName : ClassName1, ClassName2, InterfaceName1, InterfaceName2 (object list must precedes interface list) A class that implements an interface, must provide implementations for every method and property in the interface definition Slide modified by L. Lilien

83 ++READ LATER++ 12.7 Case Study: Creating and Using Interfaces (Cont.)
Common Programming Error 12.6 It is a compilation error to declare an interface member public or abstract explicitly Because they are redundant in interface-member declarations. It is also a compilation error to specify any implementation details, such as concrete method declarations, in an interface.

84 ++READ LATER++ 12.7 Case Study: Creating and Using Interfaces (Cont.)
To use an interface, a class must specify that it implements the interface by listing the interface after the colon (:) in the class declaration. A concrete class implementing an interface must declare each member of the interface with the signature specified in the interface declaration. A class that implements an interface but does not implement all its members is an abstract class It must be declared abstract Must contain an abstract declaration for each unimplemented member of the interface. Common Programming Error 12.7 Failing to declare any member of an interface in a class that implements the interface results in a compilation error.

85 12.7 Case Study: Creating and Using Interfaces (Cont.)
A programmer creates an interface that describes the desired functionality Then implement this interface in any classes requiring that functionality Like abstract classes, interfaces are typically public types Normally declared in files by themselves File name = interface name plus the.cs extension

86 12.7 Case Study: Creating and Using Interfaces (Cont.)
Example 1: Class hierarchy with interface IAge (notice “I” in “IAge”– this is a convention used for naming interfaces) Used polymorphically: by class Person by class Tree next slide

87 Definition of interface IAge
1 // Fig : IAge.cs [in textbook ed.1] 2 // Interface IAge declares property for setting and getting age. 3 4 public interface IAge 5 { int Age { get; } string Name { get; } 8 } IAge.cs Definition of interface IAge Classes implementing this interface will have to define read-only properties Age and Name

88 Definition of Age property (required) Person.cs
1 // Fig : Person.cs [in textbook ed.1] 2 // Class Person has a birthday. 3 using System; 4 5 public class Person : IAge 6 { private string firstName; private string lastName; private int yearBorn; 10 // constructor public Person( string firstNameValue, string lastNameValue, int yearBornValue ) { firstName = firstNameValue; lastName = lastNameValue; 17 if ( yearBornValue > 0 && yearBornValue <= DateTime.Now.Year ) yearBorn = yearBornValue; else yearBorn = DateTime.Now.Year; } 23 // property Age implementation of interface IAge public int Age { get { return DateTime.Now.Year - yearBorn; } } 32 Definition of Age property (required) Person.cs Class Person implements the IAge interface

89 Definition of Name property (required) Person.cs
// property Name implementation of interface IAge public string Name { get { return firstName + " " + lastName; } } 41 42 } // end class Person Definition of Name property (required) Person.cs

90 Class Tree implements the IAge interface
1 // Fig : Tree.cs [in textbook ed.1] 2 // Class Tree contains number of rings corresponding to its age. 3 using System; 4 5 public class Tree : IAge 6 { private int rings; // number of rings in tree trunk 8 // constructor public Tree( int yearPlanted ) { // count number of rings in Tree rings = DateTime.Now.Year - yearPlanted; } 15 // increment rings public void AddRing() { rings++; } 21 // property Age implementation of interface IAge public int Age { get { return rings; } } Tree.cs Class Tree implements the IAge interface Implementation of Age property ( required)

91 Definition of Name property (required) Tree.cs
30 // property Name implementation of interface IAge public string Name { get { return "Tree"; } } 39 40 } // end class Tree Definition of Name property (required) Tree.cs

92 Create array of IAge references InterfacesTest.cs
1 // Fig : InterfacesTest.cs [in textbook ed.1] // Demonstrating polymorphism with interfaces (on the objects of // disparate classes Tree and Person). 3 using System.Windows.Forms; 4 5 public class InterfacesTest 6 { public static void Main( string[] args ) { Tree tree = new Tree( 1978 ); Person person = new Person( "Bob", "Jones", 1971 ); 11 // create array of IAge references IAge[] iAgeArray = new IAge[ 2 ]; 14 // iAgeArray[ 0 ] refers to Tree object polymorphically iAgeArray[ 0 ] = tree; 17 // iAgeArray[ 1 ] refers to Person object polymorphically iAgeArray[ 1 ] = person; 20 // display tree information string output = tree + ": " + tree.Name + "\nAge is " + tree.Age + "\n\n"; 24 // display person information output += person + ": " + person.Name + "\nAge is: " person.Age + "\n\n"; 28 Create array of IAge references InterfacesTest.cs Assign an IAge reference to reference a Person object Assign an IAge reference to reference a Tree object

93 InterfacesTest.cs Program Output
// display name and age for each IAge object in iAgeArray foreach ( IAge ageReference in iAgeArray ) { output += ageReference.Name + ": Age is " + ageReference.Age + "\n"; } 35 MessageBox.Show( output, "Demonstrating Polymorphism" ); 37 } // end method Main 39 40 } // end class InterfacesTest Use foreach loop to access each element of the array InterfacesTest.cs Program Output Use polymorphism to call the property of the appropriate class

94 SELF –STUDY: 12.7 Case Study: Creating and Using Interfaces (Cont.)
Example 2: Class hierarchy with interface IShape (again notice “I” in “IShape”– this is a convention used for naming interfaces) Used polymorphically: by class Point3 (directly) by class Circle3 (derived from Point3) by class Cylinder3 (derived from Circle3) next slide

95 Definition of IShape interface
SELF –STUDY 1 // Fig : IShape.cs [in textbook ed.1] 2 // Interface IShape for Point, Circle, Cylinder Hierarchy. 3 4 public interface IShape 5 { // classes that implement IShape must implement these methods // and this property double Area(); double Volume(); string Name { get; } 11 } IShape.cs Definition of IShape interface Classes implementing the interface must define methods Area and Volume (each of which take no arguments and return a double) and a read-only string property Name

96 Class Point3 implements the IShape interface
SELF –STUDY 1 // Fig : Point3.cs [in textbook ed.1] 2 // Point3 implements interface IShape and represents 3 // an x-y coordinate pair. 4 using System; 5 6 // Point3 implements IShape interface 7 public class Point3 : IShape 8 { private int x, y; // Point3 coordinates 10 // default constructor public Point3() { // implicit call to Object constructor occurs here } 16 // constructor public Point3( int xValue, int yValue ) { X = xValue; Y = yValue; } 23 // property X public int X { get { return x; } 31 Point3.cs Class Point3 implements the IShape interface

97 SELF –STUDY set { x = value; } } 37 // property Y public int Y { get { return y; } 45 set { y = value; } } 51 // return string representation of Point3 object public override string ToString() { return "[" + X + ", " + Y + "]"; } 57 // implement interface IShape method Area public virtual double Area() { return 0; } 63 Point3.cs Implementation of IShape method Area (required), declared virtual to allow deriving classes to override

98 SELF –STUDY // implement interface IShape method Volume public virtual double Volume() { return 0; } 69 // implement property Name of IShape interface public virtual string Name { get { return "Point3"; } } 78 79 } // end class Point3 Implementation of IShape method Volume (required), declared virtual to allow deriving classes to override Point3.cs Implementation of IShape property Name (required), declared virtual to allow deriving classes to override

99 Definition of class Circle3 which inherits from Point3
SELF –STUDY 1 // Fig : Circle3.cs [in textbook ed.1] 2 // Circle3 inherits from class Point3 and overrides key members. 3 using System; 4 5 // Circle3 inherits from class Point3 6 public class Circle3 : Point3 7 { private double radius; // Circle3 radius 9 // default constructor public Circle3() { // implicit call to Point3 constructor occurs here } 15 // constructor public Circle3( int xValue, int yValue, double radiusValue ) : base( xValue, yValue ) { Radius = radiusValue; } 22 // property Radius public double Radius { get { return radius; } 30 Circle3.cs Definition of class Circle3 which inherits from Point3

100 Override the Point3 implementation of Area
SELF –STUDY set { // ensure non-negative Radius value if ( value >= 0 ) radius = value; } } 38 // calculate Circle3 diameter public double Diameter() { return Radius * 2; } 44 // calculate Circle3 circumference public double Circumference() { return Math.PI * Diameter(); } 50 // calculate Circle3 area public override double Area() { return Math.PI * Math.Pow( Radius, 2 ); } 56 // return string representation of Circle3 object public override string ToString() { return "Center = " + base.ToString() + "; Radius = " + Radius; } 63 Circle3.cs Override the Point3 implementation of Area

101 Override the Point3 implementation of Name Circle3.cs
SELF –STUDY // override property Name from class Point3 public override string Name { get { return "Circle3"; } } 72 73 } // end class Circle3 Override the Point3 implementation of Name Circle3.cs

102 Declaration of class Cylinder3 which inherits from class Circle3
SELF –STUDY 1 // Fig : Cylinder3.cs [in textbook ed.1] 2 // Cylinder3 inherits from class Circle2 and overrides key members. 3 using System; 4 5 // Cylinder3 inherits from class Circle3 6 public class Cylinder3 : Circle3 7 { private double height; // Cylinder3 height 9 // default constructor public Cylinder3() { // implicit call to Circle3 constructor occurs here } 15 // constructor public Cylinder3( int xValue, int yValue, double radiusValue, double heightValue ) : base( xValue, yValue, radiusValue ) { Height = heightValue; } 22 // property Height public double Height { get { return height; } 30 Cylinder3.cs Declaration of class Cylinder3 which inherits from class Circle3

103 Override the Point3 implementation of Volume
SELF –STUDY set { // ensure non-negative Height value if ( value >= 0 ) height = value; } } 38 // calculate Cylinder3 area public override double Area() { return 2 * base.Area() + base.Circumference() * Height; } 44 // calculate Cylinder3 volume public override double Volume() { return base.Area() * Height; } 50 // return string representation of Cylinder3 object public override string ToString() { return "Center = " + base.ToString() + "; Height = " + Height; } 57 Override the Point3 implementation of Volume Cylinder3.cs Override the Circle3 implementation of Area

104 Override the Circle3 implementation of Name Cylinder3.cs
SELF –STUDY // override property Name from class Circle3 public override string Name { get { return "Cylinder3"; } } 66 67 } // end class Cylinder3 Override the Circle3 implementation of Name Cylinder3.cs

105 Create an array of IShape references (IShape is an interface)
SELF –STUDY 1 // Fig : Interfaces2Test.cs [in textbook ed.1] 2 // Demonstrating polymorphism with interfaces in 3 // Point-Circle-Cylinder hierarchy. 4 5 using System.Windows.Forms; 6 7 public class Interfaces2Test 8 { public static void Main( string[] args ) { // instantiate Point3, Circle3 and Cylinder3 objects Point3 point = new Point3( 7, 11 ); Circle3 circle = new Circle3( 22, 8, 3.5 ); Cylinder3 cylinder = new Cylinder3( 10, 10, 3.3, 10 ); 15 // create array of IShape references IShape[] arrayOfShapes = new IShape[ 3 ]; 18 // arrayOfShapes[ 0 ] references Point3 object arrayOfShapes[ 0 ] = point; 21 // arrayOfShapes[ 1 ] references Circle3 object arrayOfShapes[ 1 ] = circle; 24 // arrayOfShapes[ 2 ] references Cylinder3 object arrayOfShapes[ 2 ] = cylinder; 27 string output = point.Name + ": " + point + "\n" + circle.Name + ": " + circle + "\n" + cylinder.Name + ": " + cylinder; 31 Create an array of IShape references (IShape is an interface) Interfaces2Test.cs Assign an IShape reference to reference a Point3 object Assign an IShape reference to reference a Circle3 object Assign an IShape reference to reference a Cylinder3 object

106 Interfaces2Test.cs Program Output
SELF –STUDY foreach ( IShape shape in arrayOfShapes ) { output += "\n\n" + shape.Name + ":\nArea = " + shape.Area() + "\nVolume = " + shape.Volume(); } 37 MessageBox.Show( output, "Demonstrating Polymorphism" ); } 40 } Use polymorphism to call the appropriate class’s method or property Interfaces2Test.cs Program Output

107 ++READ LATER++ 12.7 Case Study: Creating and Using Interfaces (Cont.)
Software Engineering Observation 12.6 Inheritance and interfaces are similar in their implementation of the is-a relationship. An object of a class that implements an interface may be thought of as an object of that interface type. Software Engineering Observation 12.7 We know that the is-a relationship exists between base classes and derived classes, and between interfaces and the classes that implement them. The is-a relationship also holds when passing an object to a method: When a method parameter receives an argument of a base class or interface type, the method polymorphically processes the object received as an argument.

108 12.7 Case Study: Creating and Using Interfaces (Cont.)
Common Interfaces of the .NET Framework Class Library Fig | Common interfaces of the .NET Framework Class Library.

109 12.8. Operator Overloading C# contains many operators that are defined for primitive types E.g., + - * / It is often useful to use operators with user-defined types E.g., user-defined complex number class with + - * Operator notation may often be more intuitive then method calls E.g., ‘a+b’ more intuitive than ‘Myclass.AddIntegers( a, b )’ C# allows programmers to overload operators to make them [polymorphically] sensitive to the context in which they are used Overloading operators is a kind of polymorphism What looks like the same operator used for different types E.g., ‘+’ for primitive type int and ‘+’ for user-defined type ComplexNumber Each time different actions performed – polymorphism at work Slide modified by L. Lilien

110 ++READ LATER++ 12.8. Operator Overloading (Cont.)
Methods define the actions to be taken for the overloaded operator They are in the form: public static ReturnType operator operator-to-be-overloaded( arguments ) These methods must be declared public and static The return type is the type returned as the result of evaluating the operation The keyword operator follows the return type to specify that this method defines an operator overload The last piece of information is the operator to be overloaded E.g., operator ‘+’:public static CompNr operator + ( CompNr x, Int y, Int z ) If the operator is unary, one argument must be specified, if the operator is binary, then two, etc. E.g., operator + shown above is ternary (3 parameters) Slide modified by L. Lilien

111 ++READ LATER++ 12.8. Operator Overloading (Cont.)
Software Engineering Observation 12.9 Use operator overloading when it makes an application clearer than accomplishing the same operations with explicit method calls. Slide modified by L. Lilien

112 12.8. Operator Overloading (Cont.)
C# enables you to overload most operators to make them sensitive to the context in which they are used. Example: Class ComplexNumber (Fig. 12.17) overloads the plus (+), minus (-) and multiplication (*) operators To enable programs to add, subtract and multiply instances of class ComplexNumber using common mathematical notation. Slide modified by L. Lilien

113 12.8. Operator Overloading (Cont.)
Example (console implementation): Class that overloads operators for adding, subtracting and multiplying complex numbers Operations on complex numbers: Let x = xR + xI * i and y= yR+ yI* i Then: x + y= (xR + yR) + (xI + yI) * i x - y= (xR - yR) + (xI - yI) * i x * y= (xR * yR – xI * yI) + (xR * yI + yR *xI) * i Slide modified by L. Lilien

114 Outline ComplexNumber.cs ( 2 of 4 )

115 Overload the plus operator (+) to perform addition of ComplexNumbers
Outline Overload the plus operator (+) to perform addition of ComplexNumbers ComplexNumber.cs ( 3 of 4 )

116 ++READ LATER++ 12.8 Operator Overloading (Cont.)
Keyword operator, followed by an operator symbol, indicates that a method overloads the specified operator Methods that overload binary operators must take two arguments— The first argument is the left operand The second argument is the right operand Overloaded operator methods must be public and static

117 ++READ LATER++ 12.8 Operator Overloading (Cont.)
Software Engineering Observation 12.10 Overloaded operators perform the same (or similar) functions on class objects as the operators perform on objects of simple types Avoid non-intuitive use of operators Software Engineering Observation 12.11 At least one argument of an overloaded operator method must be a reference to an object of the class in which the operator is overloaded This prevents programmers from changing how operators work on simple types

118 OperatorOver loading.cs
Outline Class ComplexTest (Fig. 12.18) demonstrates the overloaded operators for adding, subtracting and multiplying ComplexNumbers. OperatorOver loading.cs ( 1 of 2 )

119 OperatorOver loading.cs
Outline OperatorOver loading.cs (2 of 2 ) Add, subtract and multiply x and y using the overloaded operators, then output the results.

120 ++OPTIONAL++ 12.8. Operator Overloading (Cont.)
Example (Windows Forms implementation): The same class that overloads operators for adding, subtracting and multiplying complex numbers The following slides Slide modified by L. Lilien

121 Class ComplexNumber definition
++OPTIONAL++ 1 // Fig : ComplexNumber.cs [in textbook ed.1] 2 // Class that overloads operators for adding, subtracting 3 // and multiplying complex numbers. 4 5 public class ComplexNumber 6 { private int real; private int imaginary; 9 // default constructor public ComplexNumber() {} 12 // constructor public ComplexNumber( int a, int b ) { Real = a; Imaginary = b; } 19 // return string representation of ComplexNumber public override string ToString() { return "( " + real + ( imaginary < 0 ? " - " + ( imaginary * -1 ) : " + " + imaginary ) + "i )"; // conditional operator (?:) } 27 // property Real public int Real { get { return real; } 35 ComplexNumber.cs Class ComplexNumber definition Property Real provides access to the real part of the complex number Slide modified by L. Lilien

122 Overload the addition (+) operator for ComplexNumbers.
++OPTIONAL++ set { real = value; } 40 } // end property Real 42 // property Imaginary public int Imaginary { get { return imaginary; } 50 set { imaginary = value; } 55 } // end property Imaginary 57 // overload the addition operator public static ComplexNumber operator + ( ComplexNumber x, ComplexNumber y ) { return new ComplexNumber( x.Real + y.Real, x.Imaginary + y.Imaginary ); } // non-overloaded ‘+’ (for int’s) is used above twice // since x.Real, y.Real, x.Imaginary, y.Imaginary are all // int’s - see Lines 7-8 & 28-56 ComplexNumber.cs Overload the addition (+) operator for ComplexNumbers. Property Imaginary provides access to the imaginary part of a complex number Slide modified by L. Lilien

123 Method Add – provides an alternative to the addition operator
++OPTIONAL++ // provide alternative to overloaded + operator // for addition public static ComplexNumber Add( ComplexNumber x, ComplexNumber y ) { return x + y; // overloaded ‘+’ (just defined in lines in } // this class) used to add 2 ComplexNumbers x & y 73 // overload the subtraction operator public static ComplexNumber operator - ( ComplexNumber x, ComplexNumber y ) { return new ComplexNumber( x.Real - y.Real, x.Imaginary - y.Imaginary ); } // non-overloaded ‘-’ (for int’s) is used above twice // since x.Real, y.Real, x.Imaginary, y.Imaginary are all // int’s - see Lines 7-8 & 28-56 81 // provide alternative to overloaded - operator // for subtraction public static ComplexNumber Subtract( ComplexNumber x, ComplexNumber y ) { return x - y; // overloaded ‘-’ (just def. in lines in this } // class) used to subtract ComplexNumber y from ComplexNumber x 89 // overload the multiplication operator public static ComplexNumber operator * ( ComplexNumber x, ComplexNumber y ) { return new ComplexNumber( x.Real * y.Real - x.Imaginary * y.Imaginary, x.Real * y.Imaginary + y.Real * x.Imaginary ); } // non-overloaded ‘*’, ‘-’ and ‘+’ (for int’s) are used above Method Add – provides an alternative to the addition operator ComplexNumber.cs Method Subtract – provides an alternative to the subtraction operator Overloads the multiplication (*) operator for ComplexNumbers Overload the subtraction (-) operator for ComplexNumbers Slide modified by L. Lilien

124 1) Some .NET languages do not support operator overloading.
++OPTIONAL++ 98 // provide alternative to overloaded * operator // for multiplication public static ComplexNumber Multiply( ComplexNumber x, ComplexNumber y ) { return x * y; // overloaded ‘*’ (just def. in lines in this } // class) used to multiply 2 ComplexNumbers x & y 106 107 } // end class ComplexNumber ComplexNumber.cs Method Multiply – provides an alternative to the multiplication operator Note: 1) Some .NET languages do not support operator overloading. 2) The alternative methods: public static ComplexNumber Add ( ComplexNumber x, ComplexNumber y ) public static ComplexNumber Subtract ( ComplexNumber x, ComplexNumber y ) public static ComplexNumber Multiply( ComplexNumber x, ComplexNumber y ) for adding, subtracting and mutliplying ComplexNumbers, respectively, are needed to ensure that the ComplexNumber class can be used in such languages. (of course, it can be used only with ‘ComplexNumber Add ( x, y )’, not ‘x + y’, etc.) 3) We do not use the alternative methods in our test below. Slide modified by L. Lilien

125 OperatorOverloading.cs ++OPTIONAL++
1 // Fig 10.27: OperatorOverloading.cs [in textbook ed.1] 2 // An example that uses operator overloading 3 4 using System; 5 using System.Drawing; 6 using System.Collections; 7 using System.ComponentModel; 8 using System.Windows.Forms; 9 using System.Data; 10 11 public class ComplexTest : System.Windows.Forms.Form 12 { private System.Windows.Forms.Label realLabel; private System.Windows.Forms.Label imaginaryLabel; private System.Windows.Forms.Label statusLabel; 16 private System.Windows.Forms.TextBox realTextBox; private System.Windows.Forms.TextBox imaginaryTextBox; 19 private System.Windows.Forms.Button firstButton; private System.Windows.Forms.Button secondButton; private System.Windows.Forms.Button addButton; private System.Windows.Forms.Button subtractButton; private System.Windows.Forms.Button multiplyButton; 25 private ComplexNumber x = new ComplexNumber(); private ComplexNumber y = new ComplexNumber(); 28 [STAThread] static void Main() { Application.Run( new ComplexTest() ); } 34 OperatorOverloading.cs

126 OperatorOverloading.cs ++OPTIONAL++
private void firstButton_Click( object sender, System.EventArgs e ) { x.Real = Int32.Parse( realTextBox.Text ); x.Imaginary = Int32.Parse( imaginaryTextBox.Text ); realTextBox.Clear(); imaginaryTextBox.Clear(); statusLabel.Text = "First Complex Number is: " + x; } 44 private void secondButton_Click( object sender, System.EventArgs e ) { y.Real = Int32.Parse( realTextBox.Text ); y.Imaginary = Int32.Parse( imaginaryTextBox.Text ); realTextBox.Clear(); imaginaryTextBox.Clear(); statusLabel.Text = "Second Complex Number is: " + y; } 54 // add complex numbers private void addButton_Click( object sender, System.EventArgs e ) { statusLabel.Text = x + " + " + y + " = " + ( x + y ); } 60 // subtract complex numbers private void subtractButton_Click( object sender, System.EventArgs e ) { statusLabel.Text = x + " - " + y + " = " + ( x - y ); } 67 OperatorOverloading.cs Use overloaded addition operator to add two ComplexNumbers Use overloaded subtraction operator to subtract two ComplexNumbers

127 OperatorOverloading.cs Program Output
++OPTIONAL++ // multiply complex numbers private void multiplyButton_Click( object sender, System.EventArgs e ) { statusLabel.Text = x + " * " + y + " = " + ( x * y ); } 74 75 } // end class ComplexTest OperatorOverloading.cs Program Output Use overloaded multiplication operator to multiply two ComplexNumbers

128 OperatorOverloading.cs Program Output
++OPTIONAL++ OperatorOverloading.cs Program Output

129 ++OPTIONAL Software Engineering Case Study: Incorporating Inheritance and Polymorphism into the ATM System (Cont.) See textbook

130 The End

131 The End Material NOT currently covered in CS1120 follows this slide

132 ** SKIP *** [10.3 in textbook ed.1] Type Fields and switch Statements
Using switch to determine the type of an object Distinguish between object types, then perform appropriate action depending on object type Potential problems using switch Programmer may forget to include a type test Programmer may forget to test all possible cases in a switch When new types are added, programmer may forget to modify all relevant switch structures Every addition or deletion of a class requires modification of every switch statement determining object types in the system; tracking this is time consuming and error prone

133 [10.10 in textbook ed.1] ** SKIP ** Delegates
Sometimes useful to pass methods as arguments to other methods Example - sorting: The same method can be used to sort in the ascending order and in the descending order The only difference, when comparing elements: swap them only if the first is larger than the second for ascending order (e.g., …, 9, 3, … => …, 3, 9,… ) swap them only if the first is smaller than the second for descending order (e.g., …, 4, 7, … => …, 7, 4,… ) C# prohibits passing a method reference directly as an argument to another method. Must use delegates - delegate = a class that encapsulates sets of references to methods Analogy: Prof. Ninu Atluri requires that students submit homeworks in yellow envelopes She allows a few students to use a single yellow envelope, but does not accept any homeworks not “encapsulated” by an envelope. Prof. Atluri <--> “receiving method” (to which other methods’references are passed) homework <--> method reference (passed to another method) yellow envelope <--> delegate encapsulating references to passed methods Slide modified by L. Lilien

134 [10.10 in textbook ed.1] ** SKIP ** Delegates (Cont.)
Delegates must be declared before use Delegate declaration specifies: the parameter-list the return type of the methods the delegate can refer to E.g. delegate Comparator: public delegate bool Comparator( int element1, int element2 ); Delegates (delegate objects) are sets of references to methods E.g., delegate Comparator - a set of references to 2 methods: SortAscending and SortDescending Slide modified by L. Lilien

135 [10.10 in textbook ed.1] ** SKIP ** Delegates (Cont.)
Methods that can be referred to by a delegate, must have the same signature as the delegate E.g.: public delegate bool Comparator( int el1, int el2 ); signature of Comparator is: (int, int) -> bool Methods SortAscending or SortDescending referred to by Comparator must have the same signature ((int, int) -> bool) private bool SortAscending( int element1, int element2 ) private bool SortDescending( int element1, int element2 ) Delegate instances can then be created to refer to the methods Slide modified by L. Lilien

136 [10.10 in textbook ed.1] ** SKIP ** Delegates (Cont.)
Delegates can be passed to methods E.g., delegate Comparator can be passed to method SortArray Once a delegate instance is created (below: instance of delegate Comparator is created with new), the method it refers to (below: SortAscending) can be invoked by the method (below: SortArray) to which the delegate passed it E.g.: DelegateBubbleSort.SortArray( elementArray, new DelegateBubbleSort.Comparator( SortAscending ) ) The method to which a delegate passed methods can then invoke the methods the delegate object refers to E.g., method SortArray can invoke method SortAscending to which delegate object Comparator refers to Slide modified by L. Lilien

137 [10.10 in textbook ed.1] ** SKIP ** Delegates (Cont.)
Example – sorting (continued from slide 70) Declare delegate Comparator : public delegate bool Comparator( int element1, int element2 ); // delegate signature: (int, int) -> bool Use delegate Comparator to pass the appropriate comparison methods (SortAscending or SortDescending) to method SortArray: DelegateBubbleSort.SortArray( elementArray, new DelegateBubbleSort.Comparator( SortAscending ) ) [seen above] DelegateBubbleSort.SortArray(elementArray, new DelegateBubbleSort.Comparator( SortDescending ) ) [The passed methods (SortAscending and SortDescending) have the same signatures ((int, int) -> bool ) as delegate Comparator] Slide modified by L. Lilien

138 [10.10 in textbook ed.1] ** SKIP ** Delegates (Cont.)
Types of delegates singlecast delegate - contains one method created or derived from class Delegate (from System namespace) multicast delegate - contains multiple methods created or derived from class MulticastDelegate (from System namespace) E.g., Comparator is a singlecast delegate Bec. each instance contains a single method (either SortAscending or SortDescending) Delegates are very useful for event handling We’ll see how used for mouse click events Used for event handling - Chapters 12-14 Not discussed in CS 1120 Slide modified by L. Lilien

139 ** SKIP ** Delegates (Cont.)
1 // Fig : DelegateBubbleSort.cs [in textbook ed.1] 2 // Demonstrating delegates for sorting numbers. 3 4 public class DelegateBubbleSort 5 { public delegate bool Comparator( int element1, int element2 ); // Declare delegate Comparator, i.e., declare // signature for the method. // No implementation here (no body for Comparator). 8 // sort array using Comparator delegate public static void SortArray( int[] array, Comparator Compare ) // Reference to delegate Comparator // passed as a parameter to SortArray method. { for ( int pass = 0; pass < array.Length; pass++ ) 14 for ( int i = 0; i < array.Length - 1; i++ ) 16 if ( Compare( array[ i ], array [ i + 1 ] ) ) // if Compare returns true, elements are out of order Swap( ref array[ i ], ref array[ i + 1 ] ); } 20 // swap two elements private static void Swap( ref int firstElement, ref int secondElement ) { int hold = firstElement; firstElement = secondElement; secondElement = hold; } 29 } DelegateBubbleSort.cs Call delegate method to compare array elements Delegate Comparator definition declaration; defines a delegate to a method that takes two integer parameters and returns a boolean Method Swap, swaps the two arguments (passed by reference) Method SortArray which takes an integer array and a Comparator delegate Slide modified by L. Lilien

140 ** SKIP ** Delegates (Cont.)
1 // Fig : BubbleSortForm.cs [in textbook ed.1] 2 // Demonstrates bubble sort using delegates to determine // the sort order. // Some thing will be magic for you (e.g. button click handling) 4 using System; 5 using System.Drawing; 6 using System.Collections; 7 using System.ComponentModel; 8 using System.Windows.Forms; 9 10 public class BubbleSortForm : System.Windows.Forms.Form 11 { private System.Windows.Forms.TextBox originalTextBox; private System.Windows.Forms.TextBox sortedTextBox; private System.Windows.Forms.Button createButton; // 3 buttons private System.Windows.Forms.Button ascendingButton; private System.Windows.Forms.Button descendingButton; private System.Windows.Forms.Label originalLabel; private System.Windows.Forms.Label sortedLabel; 19 private int[] elementArray = new int[ 10 ]; 21 // create randomly generated set of numbers to sort private void createButton_Click( object sender, System.EventArgs e ) // magic here { // clear TextBoxes originalTextBox.Clear(); sortedTextBox.Clear(); 29 // create random-number generator Random randomNumber = new Random(); 32 BubbleSortForm.cs Slide modified by L. Lilien

141 ** SKIP ** Delegates (Cont.)
// populate elementArray with random integers for ( int i = 0; i < elementArray.Length; i++ ) { elementArray[ i ] = randomNumber.Next( 100 ); originalTextBox.Text += elementArray[ i ] + "\r\n"; } } 40 // delegate implementation for ascending sort // More precisely: implementation of SortAscending method which can be // passed to another method via Comparator delegate (matches its signature) private bool SortAscending( int element1, int element2 ) { return element1 > element2; } 46 // sort randomly generated numbers in ascending order private void ascendingButton_Click( object sender, System.EventArgs e ) // magic here { // sort array, passing delegate for SortAscending DelegateBubbleSort.SortArray( elementArray, new DelegateBubbleSort.Comparator( SortAscending ) ); 55 DisplayResults(); } 58 // delegate implementation for desc. sort // More precisely: implementation of SortDescending method which can be private bool SortDescending( int element1, int element2 ) { return element1 < element2; } 64 BubbleSortForm.cs To sort in ascending order, send a delegate for the SortAscending method to method SortArray Method SortAscending returns true if the first argument is larger then the second; returns false otherwise Method SortDescending returns true if the first argument is smaller then the second; returns false otherwise Slide modified by L. Lilien

142 ** SKIP ** Delegates (Cont.)
// sort randomly generating numbers in descending order private void descendingButton_Click( object sender, System.EventArgs e ) // magic here { // sort array, passing delegate for SortDescending DelegateBubbleSort.SortArray( elementArray, new DelegateBubbleSort.Comparator( SortDescending ) ); 73 DisplayResults(); } 76 // display the sorted array in sortedTextBox private void DisplayResults() { sortedTextBox.Clear(); 81 foreach ( int element in elementArray ) sortedTextBox.Text += element + "\r\n"; } 85 // main entry point for application public static void Main( string[] args ) { Application.Run( new BubbleSortForm() ); // new instance waits for button click } 91 } BubbleSortForm.cs To sort in descending order, send a delegate to the SortDescending method to method SortArray Slide modified by L. Lilien

143 BubbleSortForm.cs Program Output
** SKIP ** Delegates (Cont.) BubbleSortForm.cs Program Output


Download ppt "Polymorphism, Interfaces &"

Similar presentations


Ads by Google