Leveraging the power of Object-Oriented Programming through Polymorphism (OOP).
One of the central tenets of OOP is code reuse – the ability to avoid repeating code.
In this article, I will briefly illustrate a simple example of this principle.
I’ll begin with a simple class that will be used to build a complex model upon.
Notice it contains three attributes and one abstract method – it’s abstract because the behavior is expected to be overridden when implemented.
The class is called Employee because I needed a general enough class upon which to based other roles working in the organization.
The Supervisor will be the first type of employee I will created a template (class) for building objects.
Notice that in this class I’m overriding the behavior for the TakeVacation() method defined in the superclass.
Next, I’ll create a class to create Middle Manager objects.
Notice once again I’m overriding the behavior for the TakeVacation() method defined in the superclass.
With my Employee superclass and two subclasses built, I’m now ready to illustrate polymorphism.
First, I’ll instantiate two objects, one Supervisor, the other Middle Manager, but notice in both cases, I’m assigning their variables to an Employee object.
What is the purpose? There are two primary purposes for doing so.
First, knowing that the compiler will figure out at runtime which object’s behavior I expect, I am able to avoid having to unnecessarily declare multiple objects just to distinguish their behavior (imagine I’m using an array of objects, not two explicitly declared ones as in this example). Therefore, I only need objects declared using the Employee superclass which saved me code.
Second, since I’m able to use superclass objects, I can target that interface when building method parameter list which allows my code easier flexibility since I don’t have to keep update it. For example, let’s pretend a method takes an object as a parameter and will perform some sort of employee type of logic using that object. If my function expects a Supervisor object but later I need the function to perform logic on Middle Manager objects. I’d have to keep going back to rewrite my function logic as newer subclasses were created. However, if I target my superclass with method parameters, I never have to update my code later as new subclasses are added because the method expects an Employee object – the compiler will figure out at runtime which type of object should be expected.
In this example, I’ll call TakeVacation() on both Employee objects.
Notice the compiler accurately discerned for me when to call the method from the Supervisor class and when to call the Middle Manager behavior.