Intermediate
20 min read
What Is an sObject?
By the end of this lesson, you'll be able to:
- Explain what sObject means as the base type for every Salesforce record
- Recognize that Account, Contact, and every custom object are all sObjects
- Write a generic variable typed as sObject rather than a specific object type
Prerequisites: "Record IDs: 15 vs 18 Characters"
Every record type shares a common base
Account acc = new Account();
Contact con = new Contact();
Course_Enrollment__c enrollment = new Course_Enrollment__c();
sObject genericRecord1 = acc; // valid — Account IS an sObject
sObject genericRecord2 = con; // valid — Contact IS an sObject
sObject genericRecord3 = enrollment; // valid — even custom objects ARE sObjects
Account acc = new Account();— a standard object.Contact con = new Contact();— another standard object.Course_Enrollment__c enrollment = new Course_Enrollment__c();— a custom object.- (blank line)
sObject genericRecord1 = acc;— this is Module 11's polymorphism ("is-a" relationships) applied at the platform level — valid becauseAccountIS ansObject.sObject genericRecord2 = con;— valid —ContactIS ansObjecttoo.sObject genericRecord3 = enrollment;— valid — even custom objects AREsObjects. Every single Salesforce object, standard or custom, is fundamentally ansObject.
Why this matters: writing generic code
public void logRecordId(sObject record) {
System.debug('Record Id: ' + record.Id);
}
logRecordId(new Account(Name = 'Acme Logistics'));
logRecordId(new Contact(LastName = 'Dlamini'));
public void logRecordId(sObject record) {— accepts any kind of record —Account,Contact, or any custom object — without needing a separate overloaded version for each type.System.debug('Record Id: ' + record.Id);— becauseIdexists on everysObject.}— closes the method.- (blank line)
logRecordId(new Account(Name = 'Acme Logistics'));— passes anAccount.logRecordId(new Contact(LastName = 'Dlamini'));— passes aContact— the same method handles both. This is exactly Module 11's polymorphism, letting one method work uniformly across many concrete record types.
The trade-off: fewer specific fields available
sObject record = new Account(Name = 'Acme Logistics');
// record.Industry; // compile error — sObject alone doesn't know about Industry
Account acc = (Account) record;
System.debug(acc.Industry); // fine, now typed specifically
sObject record = new Account(Name = 'Acme Logistics');— a genericsObjectvariable.// record.Industry;— commented out because this line would not compile — ansObjectvariable only exposes what's common to every record (likeId), notAccount-specific fields.Account acc = (Account) record;— casting back to the specific type first.System.debug(acc.Industry);— now typed specifically, soIndustryis accessible. This mirrors the trade-off from Module 11's polymorphism lesson: generality in exchange for giving up type-specific access until you cast back down.
Exercise
Write a method describeRecord(sObject record) that debugs the record's Id. Call it with both a new Account and a new Contact.
Show hint
Id exists on every sObject.
What Is an sObject? Quiz
My Notes
Log in to keep private notes on this lesson.
Questions about this lesson
No questions yet — be the first to ask.
Log in to ask a question about this lesson.
Summary
sObject is the base type every Salesforce record shares — Account, Contact, a custom object, all of them are sObjects underneath, which is what makes generic, type-agnostic Apex code possible.