Theoretic question about sObject

apexobject

I am currently at module Apex Basics & Database > use sObjects lesson;
Here they told me I can use a generic sObject datatype to any fields or objects, and show me this code:

sObject sobj1 = new Account(Name='Trailhead');
sObject sobj2 = new Book__c(Name='Workbook 1');

Then he says I can cast a generic sObject to a specific type and show me this code:

// Cast a generic sObject to an Account
Account acct = (Account)myGenericSObject;
// Now, you can use the dot notation to access fields on Account
String name = acct.Name;
String phone = acct.Phone;

My question is: Shouldn't Account acct declaration be sObject acct instead?
In my head the "acct" object they have created on this example isn't a generic object, is a Account object, and then, they've cast Account again, so this doesn't make sense to me.
What seems they tried to explain me is something like the "var" variable works.
But then, they have created an integer and cast as integer.

Am I wrong?

Best Answer

Account acct = (Account)myGenericSObject; is indeed correct here.

A more complete example would be something like this

String acctName;
// This uses implicit typecasting to turn the Account into an SObject (which
//   works because Account extends/inherits from the SObject type) and we're
//   traversing upwards in the type hierarchy (more specific type -> less specific
//   type)
SObject myGenericSObject = new Account(Name = 'Trailhead');

// When using an SObject, we can really only access fields using .get()
// .get() returns a result of type 'Object', which we need to explicitly typecast
//   (that's the "(String)" part of the line) to really be able to do anything with
acctName = (String)myGenericSObject.get('Name');
system.debug(acctName);

// There may be a few occasions where you can do implicit typecasting, but
//   in general when you want to go from a generic type (e.g. SObject) to a more 
//   specific type (e.g. Account) you need to explicitly typecast
Account specificAccountObj = (Account)myGenericSObject;

// When you have a concrete/specific SObject (Account, Opportunity, 
//   My_Custom_Object__c, etc...), you can use dot notation to access fields
acctName = specificAccountObj.Name;
system.debug(acctName);

The implication here is that myGenericSObject is currently being treated as a generic SObject (but you want it to be an Account again).

The Account acct = (Account)myGenericSObject; line basically says "yes, I know that myGenericSObject looks like an SObject, but trust me, it's really an Account, and store it in a variable of type Account".

In general, the type of the two sides of an expression have to match (or at least be compatible).
The left-hand side of that expression (Account acct) dictates how the data can be used later on (i.e. it's a specific type of SObject, an Account).
The right-hand side of that expression ((Account)myGenericSObject) ensures that the resulting "type" of the expression matches that of the left-hand side.

Related Topic