As you progress in your journey as a Salesforce developer, you may find yourself writing code like this:
public Set<Id> getIds(List<Account> accounts){ Set<Id> accountIds = new Set<Id>(); for(Account acc : accounts) { accountIds.add(acc.Id); } return accountIds; }
but you might have an overloaded method containing similar code for your other objects like Deal__c
.
public Set<Id> getIds(List<Deal__c> deals){ Set<Id> dealIds = new Set<Id>(); for(Deal__c deal : deals) { dealIds.add(deal.Id); } return dealIds; }
These two methods share a similar pattern. They accept a list of a specific sObject type, create a set of Ids, iterate through to pluck the Id
field, and add it to the set.
I wouldn't want to rewrite this method for each sObject in my org. Recall WET code vs. DRY code? There's a better way. Instead, we can have a single generic method that operates on any sObject type .
All specific sObjects like Account
, Opportunity
, and CustomObject__c
are subclasses derived from a superclass called sObject
. This relationship means that every Account
is an sObject
, and every CustomObject__c
is an sObject
. This abstraction allows us to write code that can handle sObjects without knowing their specific type, making it more versatile and generic. To demonstrate, let's update the getIds()
method to accept a list of sObject
instead of a specific sObject:
public void mainMethod(List<Account> accounts, List<Deal__c> deals){ Set<Id> accountIds = getIds(accounts); Set<Id> dealIds = getIds(deals); } public Set<Id> getIds(List<sObject> objects){ Set<Id> objectIds = new Set<Id>(); for(sObject obj : objects) { objectIds.add(obj.Id); } return objectIds; }
Excellent! Thanks to the sObject
datatype, we avoided the need to create separate methods for each specific sObject type when retrieving their Id
s. This approach allows us to build a more generic and reusable codebase.