Apex provides at least two different methods for polymorphism (that is, writing code that can use objects of different classes in a uniform way):
- Standard inheritance-based polymorphism, where code is written to use one class (the base class) but objects of a derived class (defined using the "extends" keyword) may be supplied instead
- Interface-based polymorphism, where an empty interface class is defined that other classes may implement. Those classes may then be used wherever the interface class is expected.
Can anyone supply a practical example of either in use in a Salesforce context, and how they might differ?
Attribution to: Jeff Trull
Possible Suggestion/Solution #1
As I have gotten familiar with others implementations and best practices over time I tend to use both in different situations.
Interfaces:
Interfaces are absolutely fantastic for generalized API's that are re-used in many different contexts. For example: Apex-Lang's ArrayUtils.qsort I have made it a requirement in the past that all sorting outside of SOQL should be implemented using this interface. Why? because of the interface you can sort any object by its properties in a completely predictable manner, every time. No multiple dictionary mutation funny business. It cleanly provides a very clear re-usable approach to sorting objects, much like the Comparator interface in Java.
What are interfaces not good at? I have never had good luck implementing an interface as a controller for a visualforce page. Why? Because visualforce requires getter/setter methods in order to access properties and the idea of having to define each and every getter setter and then implement it defeats the purpose of re-usability.
This brings us to abstract/virtual classes.
Abstract/Virtual Classes:
In Apex abstract classes are great for creating re-usable patterns for implementing controllers (among other things). If you ever implement a visualforce page in a site you'll find that if there is any uncaught runtime error the user will only see a stanard permission exception page (hell to debug).
Instead of try catching every single contructor or initalize/action method you can write an abstract class that implements the various constructors and then use a one line method in the child class: (psuedo code)
public abstract class B{
sObject sobj;
public B(){}
public B(ApexPages.StandardController r){
try{
this.sobj = r.getRecord();
//do something standard
}
catch(Exception e){
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, e.getMessage()));
}
}
}
class A extends B{
public A(ApexPages.StandardController r){
super(r);
}
}
Attribution to: ebt
This content is remixed from stackoverflow or stackexchange. Please visit https://salesforce.stackexchange.com/questions/431