Polymorphism The best and
most concise definition I've heard for polymorphism is that it is functionality
that allows old code to call new code. This is arguably the biggest benefit of
object-oriented programming because it allows you to extend or enhance your
system without modifying or breaking existing code.Let's say you
write a method that needs to iterate through a collection of Employee
objects, calling each object's CalculatePay method. That works fine when
your company has one employee type because you can then insert the exact object
type into the collection. However, what happens when you start hiring other
employee types? For example, if you have a class called Employee and it
implements the functionality of a salaried employee, what do you do when you
start hiring contract employees whose salaries have to be computed differently?
Well, in a procedural language, you would modify the function to handle the new
employee type, since old code can't possibly know how to handle new code. An
object-oriented solution handles differences like this through polymorphism.-Using our
example, you would define a base class called Employee. You then define
a derived class for each employee type (as we've seen previously). Each derived
employee class would then have its own implementation of the CalculatePay
method. Here's where the magic occurs. With polymorphism, when you have an
upcasted pointer to an object and you call that object's method, the language's
runtime will ensure that the correct version of the method is called. Here's
the code to illustrate what I'm talking about: -using System; class Employee{
public Employee(string firstName, string lastName, int age, double payRate)
{ this.firstName = firstName; this.lastName = lastName; this.age = age; this.payRate = payRate;
}
protected string firstName;
protected string lastName;
protected int age;
protected double payRate;
public virtual double CalculatePay(int hoursWorked)
{
Console.WriteLine("Employee.CalculatePay"); return 42; // bogus value
}} class SalariedEmployee : Employee{
public SalariedEmployee(string firstName, string lastName, int age, double
payRate)
: base(firstName, lastName, age, payRate)
{}
public override double CalculatePay(int hoursWorked)
{
Console.WriteLine("SalariedEmployee.CalculatePay"); return 42; // bogus value
}} class ContractorEmployee : Employee{
public ContractorEmployee(string firstName, string lastName, int age, double
payRate)
: base(firstName, lastName, age, payRate)
{}
public override double CalculatePay(int hoursWorked)
{ Console.WriteLine("ContractorEmployee.CalculatePay"); return 42; // bogus value
}} class HourlyEmployee : Employee{
public HourlyEmployee(string firstName, string lastName, int age, double
payRate)
: base(firstName, lastName, age, payRate)
{}
public override double CalculatePay(int hoursWorked)
{
Console.WriteLine("HourlyEmployee.CalculatePay"); return 42; // bogus value
}} class PolyApp{
protected Employee[] employees;
protected void LoadEmployees()
{ Console.WriteLine("Loading
employees..."); // In a real application, we'd probably
get this // from a database. employees = new Employee[3]; employees[0] = new SalariedEmployee ("Amy",
"Anderson", 28, 100); employees[1] = new ContractorEmployee
("John", "Maffei", 35, 110); employees[2] = new HourlyEmployee
("Lani", "Ota", 2000, 5); Console.WriteLine("\n");
}
protected void CalculatePay()
{
foreach(Employee emp in
employees) { emp.CalculatePay(40); }
}
public static void Main()
{ PolyApp app = new PolyApp(); app.LoadEmployees(); app.CalculatePay();
}}Compiling and
running this application will yield the following results: -c:\>PolyApp Loading employees... SalariedEmployee.CalculatePayContractorEmployee.CalculatePayHourlyEmployee.CalculatePayNote that
polymorphism provides at least two benefits. First, it gives you the ability to
group objects that have a common base class and treat them consistently. In the
example above, although technically I have three different object types-SalariedEmployee,
ContractorEmployee,and HourlyEmployee-I can treat them all as Employee
objects because they all derive from the Employee base class. This is
how I can stuff them in an array that is defined as an array of Employee
objects. Because of polymorphism, when I call one of those object's methods,
the runtime will ensure that the correct derived object's method is called.The second
advantage is the one I mentioned at the beginning of this section: old code can
use new code. Notice that the PolyApp.CalculatePay method iterates
through its member array of Employee objects. Because this method
extracts the objects as implicitly upcasted Employee objects and the
runtime's implementation of polymorphism ensures that the correct derived
class's method is called, I can add other derived employee types to the system,
insert them into the Employee object array, and all my code continues
working without me having to change any of my original code! -
No comments:
Post a Comment