Currently it is not possible to extend a standard or custom object in Salesforce. Why would you want to do that you may ask, think about the following, how would you check the age of a contact, if they have a mobilephone, sort list of objects, serialize, deserialize, .
Contact con = [Select Birthdate from Contact][0];
Integer conAge = con.Birthdate.daysBetween(Date.Today())/365;
if (conAge > 35){
...
}
let's abstract the business logic to isAgeGreater(35) method: cleaner and reusable for any age comparison.
Contact con = [Select Birthdate from Contact][0];
Obj.IContact icontact = new Obj.IContact(con);
if (icontact.isAgeGreater(35)){
...
}
Define an Obj class that will have inner classes for all the standard objects that needs extra business logic.
1. Constructor for 1 object
2. Constructor for List of objects
3. Methods with business logic getAge, hasMobileNumber, add more if needed.
4. Sorting by any field by assigning SORT_BY
5. Sorting by any direction by assigning SORT_DIRECTION (DESC, ASC)
6. Checking if two objects are equals
7. Serialize object
8. Deserialize object
public class Obj {
public static String NAME_SORT = 'Name';
public static String EMAIL_SORT = 'Email';
public static String SORT_BY = NAME_SORT;
public static String SORT_DESC = 'DESC';
public static String SORT_ASC = 'ASC';
public static String SORT_DIRECTION = SORT_ASC;
public class IContact implements Comparable{
private Contact con;
private List<Contact> cons;
private List<IContact> conLst;
public IContact(List<Contact> cons){
this.cons = cons;
this.conLst = new List<IContact>();
for (Contact con : cons){
conLst.add(new IContact(con));
}
}
public IContact(Contact con){
this.con = con;
}
public Contact getContact(){
return con;
}
public Boolean hasMobile(){
return con.MobilePhone!=null;
}
public Integer getAge(){
return con.Birthdate!=null ? (con.Birthdate.daysBetween(Date.Today())/365) : 0;
}
public Boolean isAgeGreater(Integer compareAge){
Integer contactAge = getAge();
return contactAge > 0 ? compareAge < contactAge : false;
}
public List<IContact> getList(){
return conLst;
}
public List<IContact> sort(){
conLst.sort();
return conLst;
}
private Integer sortByName(Contact compare){
Integer compVal = 0;
if (compare.Name < con.Name){
return SORT_DIRECTION.equals(SORT_ASC) ? 1 : -1;
} else if (con.Name < compare.Name){
return SORT_DIRECTION.equals(SORT_ASC) ? -1 : 1;
}
return compVal;
}
private Integer sortByEmail(Contact compare){
Integer compVal = 0;
if (compare.Email < con.Email){
return SORT_DIRECTION.equals(SORT_ASC) ? 1 : -1;
} else if (con.Email < compare.Email){
return SORT_DIRECTION.equals(SORT_ASC) ? -1 : 1;
}
return compVal;
}
public Integer compareTo(Object obj){
if (SORT_BY.equals(NAME_SORT)){
Contact compare = ((IContact)obj).con;
return sortByName(compare);
} else if (SORT_BY.equals(EMAIL_SORT)){
Contact compare = ((IContact)obj).con;
return sortByEmail(compare);
}
return 0;
}
public Boolean isEquals(Contact concompare){
return System.equals(con, concompare);
}
public Integer getHashCode(){
return System.hashCode(con);
}
public String serialize(){
return JSON.serialize(this);
}
public IContact deserialize(String jsonCon){
return (IContact)JSON.deserialize(jsonCon, IContact.class);
}
}
}
Testing standard object Wrapper
List<Contact> contacts = [Select Id, Name, MobilePhone, Birthdate from Contact];
Obj.SORT_BY = Obj.NAME_SORT;
Obj.SORT_DIRECTION = Obj.SORT_ASC;
List<Obj.IContact> icontacts = new Obj.IContact(contacts).sort();
for (Obj.IContact c : icontacts){
System.debug(c.hasMobile());
System.debug(c.getAge());
System.debug(c.getHashCode());
System.debug(c.isEquals(c.getContact()));
}