In the last article we looked at classes to see if they were as useful as some would say. Some of the most basic things that object oriented programming gives to a developer, at least on the surface, appear to be just convenience. They are great and make our lives easier, but can be dealt with in other ways. I want us to look at just one object oriented concept that takes us beyond useful and really makes objects matter in our development. So let’s continue with our employee scenario that we looked briefly at last time. Employees are people as we learned and we saw the use of that. Now let’s consider it a step deeper. As the owner of a company you have a wonderful year and want to give a bonus to all your employees. However managers and workers will not get the same bonus. How does your application handle it all. You could have complicated code that would figure out the what type of employee each employee is and then would do something different based on what type the employee is, or you could have polymorphism. Just the sentence makes it seem like it is going to be so much easier.
To start let’s take a look at just what polymorphism is. In keeping with the goal of everything being simple and understandable at any level here is an overly simplistic definition that misses many of the finer points of polymorphism. Polymorphism allows you to treat a series of classes that have the same base class or interface as the same type of object. For those of you that want to look deeper into the definition before we get into a code sample, you can look here. What does this mean for our example though? Well we have a common base class Employee. We place a GiveBonus method in Employee as well as each of our subclasses. When it is time to give bonuses we just call GiveBonus on all employees and it is done. Of course under the hood there is still the finding out what type it is and doing something different logic. The wonderful thing is we don’t have to worry about it at all. Let’s take a look at how it works.
I have added a single method to our Employee class that we use last time.
|
public virtual void GiveBonus()
{ Console.WriteLine("If this method runs you don't get a bonus"); } |
Mostly this is very similar to what we have already looked at except I have used the word virtual. In the future we will look at exactly what all we can do with different keywords, but for our sake now putting in that keyword is what allows me to override or change the functionality in derived classes. I have also created two classes that each derive from Employee.
|
public class Manager : Employee
{ public override void GiveBonus() { Salary += 10000; Console.WriteLine("{0} was given a $10000 bonus",Name); } } public class Worker : Employee
{ public override void GiveBonus() { Salary += 5000; Console.WriteLine("{0} was given a $5000 bonus",Name); } } |
Again these simplistic classes look a lot like what we have been doing in the past two articles. The only new thing is the keyword override in each of the methods. Again a detailed look at the keywords is for future articles, but here is the basic break down. If you call give bonus on an Employee object you will get the message “If this method runs you don’t get a bonus”. If you call GiveBonus on a Manager it overrides the Employee functionality and gives a $10000 bonus, and if you call it on a Worker then it will override the Employee functionality with a $5000 bonus. So as you can see this is really simple code that we did not have to worry with what was going on. So let’s create some objects and see how hard it is to tell the application which method to call.
|
List<Employee> employees = new List<Employee>();
employees.Add(new Manager() { Name = "Jimmy", Salary = 100000 }); employees.Add(new Worker() { Name = "James", Salary = 65000 }); employees.Add(new Manager() { Name = "John", Salary = 85000 }); employees.Add(new Worker() { Name = "Jacob", Salary = 45000 }); foreach (Employee emp in employees) |
This code actually has several things that we have not seen so let’s look at it line by line. First I create a List that will hold Employee objects in it called employees. This list will only accept Employee objects. I could not put a Person object in the list because all Employee objects are a Person, but not all Person objects are an Employee. I am able to put in Manager and Worker objects all that I want. If you remember back to my last article you will understand that all Manager’s and Worker’s are Employees based on the inheritance listed above. So I have added two Manager’s and two Worker’s to that List. So far things are fairly standard and we have a list of all of our Employees. Let’s try to give them all a bonus. I have a simple foreach loop that looks at each Employee one at a time and gives them a bonus. Because of Polymorphism our results are exactly what we would like.
When we run this application we get the following output.
| Jimmy was given a $10000 bonus Your new salary with bonus is 110000 James was given a $5000 bonus Your new salary with bonus is 70000 John was given a $10000 bonus Your new salary with bonus is 95000 Jacob was given a $5000 bonus Your new salary with bonus is 50000 |
Notice that we never had to tell it anything about which type of Employee we were working with. Everything works for us right out of the box because of Polymorphism. This is certainly not the only benefit of working with classes, but as you can see considering some of the hoops we could have had to jump through we are really in good shape and this code is fully functional out of the box and very simple to create.
