Ok... so that's a round about way of saing, if I return a type of "User" is it true in all circumnstances that any orphaned variables still remain somewhere attached to that object? Somewhere in memory perhaps? In my example, in main(), is it possible, somehow, somewhere, someway to determine jimmy's password just from examining the User object that was returned?
Your getUser method creates a SecretUser instance. This will always be a SecretUser instance - you cannot convert it to another type.
You are referencing it with a User object reference ('user'). This means that (without any casting) you can only access the User specific parts of the instance. However, there is nothing to stop you referencing it with a SecretUser reference and then all parts of the instance will become asccessible.
The head first books explain casting pretty good. your object is like a tv, and your reference variable is like a remote.
so, you create a SecretUser object. That's like a TV that has picture-in-picture (PiP). you decide to connect it to a User reference - that's like a remote that doesn't have a button for PiP. The TV is still capable of doing it, you just don't have a button to turn it on.
Anyone else can get a remote that DOES have the PiP buttons, and if they use it, the PiP will come on.
A cast doesn't change the OBJECT, it only let's you connect a more or less 'sophisticated' reference to that object.
There are only two hard things in computer science: cache invalidation, naming things, and off-by-one errors