Presentation is loading. Please wait.

Presentation is loading. Please wait.

Questions from last lesson

Similar presentations


Presentation on theme: "Questions from last lesson"— Presentation transcript:

1 Questions from last lesson
Week 5: Polymorphism Questions from last lesson Classes vs Objects Properties Inheritance Homework and Practical at end of slides

2 Chapter 10 – Object-Oriented Programming: Polymorphism
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

3 Polymorphism allows programmers to write:
10.1 Introduction Polymorphism allows programmers to write: Programs that handle a wide variety of related classes in a generic manner Systems that are easily extensible

4 10.2 Derived-Class-Object to Base-Class-Object Conversion
Class hierarchies Can assign derived-class objects to base-class references Can explicitly cast between types in a class hierarchy An object of a derived-class can be treated as an object of its base-class Array of base-class references that refer to objects of many derived-class types Base-class object is NOT an object of any of its derived classes

5 Definition of class Point
1 // Fig. 10.1: 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

6 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

7 Definition of class Circle which inherits from class Point
1 // Fig. 10.2: Circle.cs 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

8 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

9 Assign a Point reference to reference a Circle object
1 // Fig. 10.3: PointCircleTest.cs 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(); 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): " + circle2.ToString(); 32 output += "\nArea of circle1 (via circle2): " + circle2.Area().ToString( "F" ); 35 Create a Point object PointCircleTest.cs Assign a Point reference to reference a Circle object Create a Circle object Use base-class reference to access a derived-class object Assign a Circle reference to reference a Point object (downcast) Use derived-class reference to access a base-class object

10 PointCircleTest.cs Program Output
// attempt to assign point1 object to Circle reference if ( point1 is Circle ) { circle2 = ( Circle ) point1; 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 if point1 references a Circle object – it cannot, because of the downcasting on line 28 PointCircleTest.cs Program Output

11 10.3 Type Fields and switch Statements
Using switch to determine the type of an object Distinguish between object, 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 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 in the system; tracking this is time consuming and error prone

12 10.4 Polymorphism Examples
Quadrilateral base-class Rectangle derived-class Square derived-class Parallelogram derived-class Trapezoid derived-class Method perimeter might need to be invoked on all classes With a Quadrilateral reference, C# polymorphically chooses the correct overriding method in the derived-class from which the object is instantiated

13 10.4 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

14 10.5 Abstract Classes and Methods
Cannot be instantiated Used as base classes Class definitions are not complete – derived classes must define the missing pieces Can contain abstract methods and/or abstract properties Have no implementation Derived classes must override inherited abstract methods and properties to enable instantiation

15 10.5 Abstract Classes and Methods
Abstract classes are used to provide appropriate base classes from which other classes may inherit (concrete classes) Abstract base classes are too generic to define real objects To define an abstract class, use keyword abstract in the declaration To declare a method or property abstract, use keyword abstract in the declaration; abstract methods and properties have no implementation

16 10.5 Abstract Classes and Methods
Concrete classes use the keyword override to provide implementations for all the abstract methods and properties of the base-class 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

17 10.6 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

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

19 Class Point2 inherits from class Shape
1 // Fig. 10.5: 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

20 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

21 Definition of class Circle2 which inherits from class Point2
1 // Fig. 10.6: 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

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

23 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

24 Class Cylinder2 derives from Circle2
1 // Fig. 10.7: 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

25 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

26 Assign a Shape reference to reference a Point2 object
1 // Fig. 10.8: 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; 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

27 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

28 10.7 sealed Classes and Methods
sealed is a keyword in C# sealed methods cannot be overridden in a derived class Methods that are declared static and private, are implicitly sealed sealed classes cannot have any derived-classes Creating sealed classes can allow some runtime optimizations e.g., virtual method calls can be transformed into non-virtual method calls

29 10.8 Case Study: Payroll System Using Polymorphism
Base-class Employee abstract abstract method Earnings Classes that derive from Employee Boss CommissionWorker PieceWorker HourlyWorker All derived-classes implement method Earnings Driver program uses Employee references to refer to instances of derived-classes Polymorphism calls the correct version of Earnings

30 Definition of abstract class Employee
1 // Fig. 10.9: 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

31 // 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 Declaration of abstract class Earnings – implementation must be provided by all derived classes Employee.cs

32 Definition of class Boss – derives from Employee
1 // Fig : 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 Boss.cs Definition of class Boss – derives from Employee

33 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

34 Definition of class CommissionWorker – derives from Employee
1 // Fig : 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 CommisionWorker.cs Definition of class CommissionWorker – derives from Employee

35 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

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

37 Definition of class PieceWorker – derives from Employee
1 // Fig : 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 PieceWorker.cs Definition of class PieceWorker – derives from Employee

38 // 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)

39 Definition of class HourlyWorker – derives from Employee
1 // Fig : 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 HourlyWorker.cs Definition of class HourlyWorker – derives from Employee

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

41 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

42 Assign Employee reference to reference a Boss object
1 // Fig : 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"; 26 employee = commissionWorker; 28 output += GetString( employee ) + commissionWorker + " earned " + commissionWorker.Earnings().ToString( "C" ) + "\n\n"; 32 employee = pieceWorker; 34 EmployeesTest.cs Assign Employee reference to reference a Boss object Use method GetString to polymorphically obtain salary information. Then use the original Boss reference to obtain the information

43 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 " + worker.Earnings().ToString( "C" ) + "\n"; } 56 } Definition of method GetString, which takes as an argument an Employee object. EmployeesTest.cs Program Output Polymorphically call the method of the appropriate derived class

44 10.9 Case Study: Creating and Using Interfaces
Interfaces specify the public services (methods and properties) that classes must implement Interfaces provide no default implementations vs. abstract classes which may provide some default implementations Interfaces are used to “bring together” or relate disparate objects that relate to one another only through the interface

45 10.9 Case Study: Creating and Using Interfaces
Interfaces are defined using keyword interface Use inheritance notation to specify a class implements an interface (ClassName : InterfaceName) Classes may implement more then one interface (a comma separated list of interfaces) Classes that implement an interface, must provide implementations for every method and property in the interface definition Example: interface IAge that returns information about an object’s age Can be used by classes for people, cars, trees (all have an age)

46 Definition of interface IAge
1 // Fig : IAge.cs 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

47 Definition of Age property (required) Person.cs
1 // Fig : Person.cs 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

48 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

49 Class Tree implements the IAge interface
1 // Fig : Tree.cs 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)

50 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

51 Create array of IAge references InterfacesTest.cs
1 // Fig : InterfacesTest.cs 2 // Demonstrating polymorphism with interfaces. 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

52 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

53 Definition of IShape interface
1 // Fig : IShape.cs 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

54 Class Point3 implements the IShape interface
1 // Fig : Point3.cs 2 // Point3 implements interface IShape and represents 3 // an x-y coordinate pair. 4 using System; 5 6 // Point3 implements IShape 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

55 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

56 64 // implement interface IShape method Volume
public virtual double Volume() { return 0; } 69 // implement property Name of IShape 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

57 Definition of class Circle3 which inherits from Point3
1 // Fig : Circle3.cs 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

58 Override the Point3 implementation of Area
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

59 Override the Point3 implementation of Name Circle3.cs
// 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

60 Declaration of class Cylinder3 which inherits from class Circle3
1 // Fig : Cylinder3.cs 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

61 Override the Point3 implementation of Volume
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

62 Override the Circle3 implementation of Name Cylinder3.cs
// 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

63 Create an array of IShape references Interfaces2Test.cs
1 // Fig : Interfaces2Test.cs 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 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

64 Interfaces2Test.cs Program Output
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

65 10.10 Delegates Sometimes useful to pass methods as arguments to other methods Delegates are sets of references to methods Delegate objects can be passed to methods; methods can then invoke the methods the delegate objects refer to Delegates that contain one method are known as singlecast delegates and are created or derived from class Delegate Delegates that contain multiple methods aare known as multicast delegates and are created or derived from class MulticastDelegate

66 10.10 Delegates Delegates must be declared before use A delegate declaration specifies the parameters and return type of the methods the delegate can refer to Methods who can be referred to by a delegate, must have the same signature as the delegate Delegate instances can then be created to refer to a method(s) Once a delegate instance is created, the method it refers to can be invoked

67 Call delegate method to compare array elements DelegateBubbleSort.cs
1 // Fig : DelegateBubbleSort.cs 2 // Demonstrating delegates for sorting numbers. 3 4 public class DelegateBubbleSort 5 { public delegate bool Comparator( int element1, int element2 ); 8 // sort array using Comparator delegate public static void SortArray( int[] array, Comparator Compare ) { 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 ] ) ) 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 } Call delegate method to compare array elements DelegateBubbleSort.cs 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

68 BubbleSortForm.cs 1 // Fig. 10.25: BubbleSortForm.cs
2 // Demonstrates bubble sort using delegates to determine 3 // the sort order. 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; 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 ) { // clear TextBoxes originalTextBox.Clear(); sortedTextBox.Clear(); 29 // create random-number generator Random randomNumber = new Random(); 32 BubbleSortForm.cs

69 33 // 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 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 ) { // sort array, passing delegate for SortAscending DelegateBubbleSort.SortArray( elementArray, new DelegateBubbleSort.Comparator( SortAscending ) ); 55 DisplayResults(); } 58 // delegate implementation for descending sort 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

70 65 // sort randomly generating numbers in descending order
private void descendingButton_Click( object sender, System.EventArgs e ) { // 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() ); } 91 } BubbleSortForm.cs To sort in descending order, send a delegate to the SortDescending method to method SortArray

71 BubbleSortForm.cs Program Output

72 10.11 Operator Overloading C# contains many operators (such as + and - ) that are defined for some primitive types It is often useful to use operators with user-defined types (e.g., a complex number class) Operator notation may often be more intuitive then method calls C# allows programmers to overload operators to make them sensitive to the context in which they are used

73 10.11 Operator Overloading 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 (such as +, -, *, etc.) If the operator is unary, one argument must be specified, if the operator is binary, then two, etc.

74 Class ComplexNumber definition
1 // Fig : ComplexNumber.cs 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 )"; } 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

75 Overload the addition (+) operator for ComplexNumbers.
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 ); } 65 ComplexNumber.cs Overload the addition (+) operator for ComplexNumbers. Property Imaginary provides access to the imaginary part of a complex number

76 Method Add – provides an alternative to the addition operator
// provide alternative to overloaded + operator // for addition public static ComplexNumber Add( ComplexNumber x, ComplexNumber y ) { return 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 ); } 81 // provide alternative to overloaded - operator // for subtraction public static ComplexNumber Subtract( ComplexNumber x, ComplexNumber y ) { return x - y; } 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 ); } 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

77 98 // provide alternative to overloaded * operator // for multiplication public static ComplexNumber Multiply( ComplexNumber x, ComplexNumber y ) { return x * y; } 106 107 } // end class ComplexNumber ComplexNumber.cs Method Multiply – provides an alternative to the multiplication operator

78 OperatorOverloading.cs 1 // Fig 10.27: OperatorOverloading.cs
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

79 Use addition operator to add two ComplexNumbers
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 addition operator to add two ComplexNumbers Use subtraction operator to subtract two ComplexNumbers

80 OperatorOverloading.cs Program Output
// 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 multiplication operator to multiply two ComplexNumbers

81 OperatorOverloading.cs Program Output

82 Homework and Practical
Self-Review Exercises Practical Exercise 10.6 (page 437) Exercise 10.7 (page 437) Exercise 10.8 (page 437)


Download ppt "Questions from last lesson"

Similar presentations


Ads by Google