Polywhatsthatnow? Polymorphism ” is the ability of one type, A, to appear as and be used like another type, B.”
It is a facet of OOP and can best be described using the good ol’ example of the ‘Shape’ class problem (thanks Java!). Let’s suppose we’d like to create an application that drew a number of shapes on a page. At the time of analysis we know that we want to immediately support circles, but to future-proof our application we need to support the drawing of any shapes. Being Pretty Darn Good Developers(tm) we realise we should create a Shape class that has a single method used to draw itself, and any specific shapes should be derived from this class, and override that method. Make sense? Didn’t think so.
In our worked example I’ll use colours (Colour = Color my American friends:P) instead of shapes, namely, we have a repeat-tag that will run over a list of classes. Each of these classes have a getColour() method, but certain classes are expected to return specific colours. That’s right we need a list of classes, so they need to be the same class type, but the same method in each must return different values (let’s assume without the use of conditional logic statements). Enough dilly-dallying, let’s get our code on.
To start with we’ll need an interface that dictates the ‘signature’ required of our classes.
[code language=”java”]
public interface ColourInt {
String getColour();
}
[/code]
We’re also going to need a base colour class that ‘implements’ our interface.. Note the ‘virtual’ keyword, this allows the class to be inherited, and the method to be overridden.
[code language=”java”]
public virtual class ColourClassBase implements ColourInt{
public virtual String getColour(){
return ‘blue’;
}
}
[/code]
Next we’ll code up some extensions of this base class. Note the ‘extends’ and ‘override’ keywords used to inherit the base class, and override it’s method.
[code language=”java”]
public class Green extends ColourClassBase{
public virtual override String getColour(){
return ‘green’;
}
}
[/code]
[code language=”java”]
public class Orange extends ColourClassBase{
public virtual override String getColour(){
return ‘orange’;
}
}
[/code]
So we’ve got our backendish logic, now we need a way to expose it to the world. First up the page-controller,
[code language=”java”]
public class ColoursController {
public List<ColourClassBase> colours{get;set;}
public ColoursController(){
colours = new List<ColourClassBase>();
colours.add(new ColourClassBase());
colours.add(new Orange());
colours.add(new Green());
}
}
[/code]
And then the page that uses it,
[code language=”java”]
<apex:page controller="ColoursController" showheader="false" standardstylesheets="false">
<apex:repeat value="{!colours}" var="c">
outputPanel layout="block" style="font-family: Georgia; font-size: 24px">
outputText value="Aweful Colour Combination" style="color:{!c.colour};"/>
</apex:outputPanel>
</apex:repeat>
</apex:page>
[/code]
This demo’s nothing to write home about, but I thought I’d put it up so that you know I’m not trying to pull a fast one on you. In the real world polymorphism requires a substantial amount of analysis and technical architecturing, but the value becomes apparent when you need to plug another class type (in our case a colour) into your application. That, and you get to feel real smarts-like.
Merry Christmas everyone, and goodwill to all.
I wonder, would this example be better classified as ‘inheritance’? Polymorphism would require a single class to extend several other classes.
While polymorphism is not directly supported in Apex, it appears possible with ‘interface’ and ‘implements’.
Agreed. There is a general definition of polymorphism, which has standard implementations within languages, but which varies across languages. I have amended the code to include Interface implementation (I was totally just checking if anyone actually reads this stuff;) and chosen to mimic the Java pattern adopted for polymorphism.
The use of interfaces in the example code certainly appears to come closer to polymorphism than inheritance. Although, I haven’t yet had a need to use it in Apex. I try to stay on the ‘happy path’ of using inheritance and instance methods when object modeling to reduce my long-term support tail 🙂
I recall when C# did everyone a great service by abandoning polymorphism in favor of multi-interface decoration on a class. Apex appears to be supporting a similar convention.
Again this makes sense. Newer OOP principles are tending to abandon polymorphism (and some are going as far as throwing inheritance in the bin) in order to avoid the all too common problem of tall, brittle inheritance hierarchies. I have found a few situations where Polymorphism makes sense (mostly around abstracting 3rd-party comms), but I’m sure I’m far from best practices. The input is appreciated.. I think I’ve got some reading to do:)
Thank you for writing this up. I can think of a million reasons to use this.
However, one especially useful case for abstracting your classes is in custom components. This comes to mind because I recently had a case on this. For instance, let’s say you have a custom component that displays a sorted list of sObjects with a checkbox next to it. Typically, you would have a wrapper class that holds the checkbox Boolean value. If you define a generic interface for the wrapper class, you can specify the interface as the attribute’s type and pass in any implementation class.
e.g.
public interface Checklistable {
public SObject record;
public Boolean checked;
}
All that’s left is to write implementations of Checklistable. The beauty is that this component becomes more generalized than, say, passing in a list of sObjects and creating the wrapper in the component’s controller.
Another great example of this can be found on our developer site. It goes into detail on controller-to-controller communication.
http://wiki.developerforce.com/index.php/Controller_Component_Communication
Good to hear 🙂 I’m not sure if you’ve seen it, but I’ve implemented the framework you mention with Ron Hess’s recaptcha component.
nice
Looks like the component got cut out. Here’s an escaped version:
<apex:component >
<apex:attribute type=”Checklistable[]” name=”Checklist” description=”A list of sObjects that can be checked for selection.” />
</apex:component>
As always, a great post, Wes! 🙂