It's been years since I thought of this, but I am training some real juniors soon and need to explain what an object is to someone who doesn't know what it is.
Based on what you use in the real world, what are the key points of objects that I should focus on explaining. For example:
- Access Levels
- Inheritance
- Encapsulation
- Polymorphism
- Abstraction
- Interfaces
I would try starting with actual code. Hopefully they're at least slightly familiar with some language. Write a simple program without using any classes or OO design at all, and then show how it can be made clearer or easier to maintain or whatever, if you redo it using classes.
A good example would probably be something where there are several functions that all use the same set of variables. For example (this is just the first example I could think of. You could probably think of much better ones -- hopefully something that doesn't seem too contrived and resembles something that you would actually write for a real-world project):
You write the code above, then at some point later, you decide that you'd also like to include the person's email address and username. Or you are dealing with two different people. You could easily end up with unwieldy functions that take several arguments, or have zillions of variables to keep track of. Or you could write a Person class, and you'd just call:
Again, probably not the best example. And I do agree with mad-j that these little "car" and "person" examples aren't always great. But I think if you presented the example as a solution to an actual problem that comes up while writing code, it might be clearer.
Same thing with inheritance. The idea is based on the real-world understanding that "An X is a certain type of Y" but the reason we do it is to make code easier to read and write. I don't think I really understood inheritance until the first time I found myself writing two classes with a lot in common, and thinking, "Wait. These have a lot of the same properties. Maybe I should put their common properties into a superclass!"
The animal/car metaphors exist to explain the philosophy of object oriented design, which is far more important to understand than just the implementation.
If you skip the metaphors and start with just "it's just variables and functions to deal with them", you're missing any description of responsibility. I constantly deal with developers who give no consideration to class responsibility (see CRC Cards), but instead put data and methods into classes wherever they happen to be editing at the time.
You also miss out on "tell, don't ask". The animal metaphor works well here. In OO, I tell the dog to clean himself. I don't ask him how he's going to do it, because that's a black box I don't want to see inside. The dog knows so I don't need to.
Just be sure to teach your students that these are just metaphors, not the actual thing. A "perfect storm" in the "mortgage meltdown" does not actually involve either storms or anything melting.
I would go from Access Levels and Encapsulation and move out from there. Encapsulation is a reasonably simple concept to grasp and has some clear benefits. From there you can talk about abstraction, inheritance and polymorphism quite easily.
As an undergraduate I found Encapsulation to be an good anchoring concept in a quite abstract area.
One of the things I find many people get confused about in OOP are actual instances of an object. That you have the ability to create multiple instances of the same class, independent of one another, seems to blow peoples' minds. If you're going to go with the usual "physical object" analogy, make sure you talk about how you can have multiple instances of said objects and how they can interact with one another as well as with themselves.
For example, take the classic "car" example. Now you have your driver program "road" which has a "carCrash(Car car1, Car car2)" function. Explain how the objects interact with one another.
The only problem with analogies like this are that, in my experience anyway, they tend to break down when you start talking about static variables/functions. I guess what I'm trying to say is that no analogy is perfect, so try not to rely on them too much.
Sometimes it is hard for beginners to understand how objects relate to program execution. ("Ok, I have a Person object I can instantiate as 'Jerry', but where do I perform the instantiation? What creates Jerry? Ok, then what creates that? Where does it all start?")
Try a universe analogy. The types in your program represent, at various levels of abstraction, all the possible objects that can exist in the universe. Make sure to show them the big bang (program entry point)! This will also show them why global variables in OOP don't make sense. Then you can dive right into OOP principles.
I like the "Vehicle" example. Many things can be vehicles (abstract class), but they all have something in common - they can move from a to be at some speed. Then there can be different classes of vehicles: gound vehicles, some moving in water, some in the air.
So you have another level of abstraction - all vehicles in the air for example need an altitude member.
I guess you get the picture. This explains most of the points you've given above.