可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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
回答1:
Back when I was learning OOP, I was puzzled by all these "car / animal / whatever" metaphors. They didn't help me at all. Then someone said that a class/object is just a set of variables (class members) and functions to deal with them (methods) - which is actually true. It was that simple!
Using all these popular metaphors is just misleading people, IMHO. Cars don't have that much in common with OOP. It's easy to understand these metaphors when you already know what they mean, but trying to begin with them... no.
回答2:
I like the original metaphor used by Alan Kay, who coined "object-oriented programming": Objects are like cells in a body. They are each programmed with their own behaviors and communicate by passing messages to one another, which they again respond to with their own internally defined behavior. No one cell knows what's inside another — they just know how to handle their own tasks and communicate with each other.
回答3:
If you want something really useful, don't forget to explain why. That's a concept that seems to be frequently missed - why is this useful...
回答4:
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.
回答5:
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.
回答6:
I would go by Grady Booch definition: An Object is one which has a State, Behaviour and Identity. Member variables contribute to State; Methods contribute to Behaviour and some
unique attributes contribute to identity. For eg., email could be an
identity attribute for a Person Object.
回答7:
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.
回答8:
As always, it really does depend on the language background they're coming from. Not every language implements OO paradigms the same way, sometimes it's possible to use an OO approach in a language that isn't stricly OO at all.
Generally, access levels are important to mention. Why should properties generally be private? What's the point of having getters and setters? This is a good place to contrast objects with collections like maps or arrays (even if they can be implemented as objects rather than primitives).
Inheritance and polymorphism should go hand-in-hand. This is a matter of abstraction, though. Explaining the difference between abstract base classes and interfaces is probably more of a language problem again -- some languages allow multiple inheritance, others only allow multiple interfaces.
Encapsulation is pretty straightforward if you got the access levels sorted out. Again, depending on the language you might want to explain inner classes and such, abstract the OO idea even further with anonymous classes maybe.
I find what works best is to start with something familiar: related functions and variables. Learning what should be an object and what object a property or method should belong to is tough, so start with clear cases.
A database handler can be a good example, or maybe an email (create a new email, set its headers and content, attach files and send it -- pretty straightforward and familiar even to non-programmers, but a perfect example for thinking in terms of objects (email, contacts; maybe even mailboxes, servers), methods (create, send, attach, set) and properties (headers, content, attachments)).
What's important is this: even if your students have some (non-OO) programming background, adjusting to OOP is a process, but "getting it" often isn't. I've heard many people describe it as a sudden event rather than a smooth transition. Of course the "calibration" is a long-term process: you need to figure out when it makes sense to create new classes and when a few temporary variables, an array or utility functions (depending on your language) will suffice, but this needs practice, not teaching.
回答9:
I prefer the approach used in "Object-Oriented Design and Patterns" by Hortsmann. If I recall correctly, the approach was to read a problem statement and identify the objects, their methods, relations, and other components using a simple pattern. For instance, an object is a noun, so all nouns would be candidate objects.
The book itself is highly recommended. After establishing what an object is, it uses some clearly defined and simple examples to discuss inheritance, interfaces, and many design patterns like the singleton.
Haha...so I guess I really suggest you let someone else do it... an author(ity).
回答10:
If I were trying to explain classes and objects to someone completely unfamiliar with programming, I would probably use something along the lines of the following:
A class is just a "recipe for a thing", the class is made of different types of "ingredients" that have different characteristics (i.e. PODs and functions/methods).
So, in that it only contains descriptions of a layout (building blocks) and functionality.
Ingredients may be of different type: "data" in that they contain actual data fields (think facts stored in variables/fields), and "action" in that they contain specific methods to do things.
Some ingredients may be secret, you may not want to share all ingredients or you may not want to share some specific ways of doing specific things with the recipe (encapsulation).
So, you as the cook have the possibility to restrict access to ingredients, so that users of your recipe have to adhere to your recipe and simply use "pre-canned" steps (methods) of doing things that you provide (without them necessarily knowing what it is about):
Some ingredients may be meant to be only internally visible (private access) because they are only really relevant to that specific instance/manifestation of the recipe/class, while others may also be meant to be accessible from recipes that are based on this recipe (think customizations), that derive from it (protected access).
And then there are ingredients that shall be generally visible and accessible to all users of the recipe (public), because they compose the "frontend" or "interface" of the final product (they don't necessarily need to know about internals/low level implementation stuff).
Once a class is actually used to implement a particular recipe, a new object is created (the class gets instantiated): A chocolate cake is just one manifestation/version of the chocolate cake recipe. There can be many other versions using the same "recipe".
If you were to combine multiple recipes (e.g. chocolate cake and lemon cake), you can create a new recipe that derives from both recipes, basically creating a completely new recipe that shares the characteristics of the original recipes (multiple inheritance).
By basing new recipes on existing ones using inheritance, changes in the original recipe can be directly imported into the new recipe. Similarly, having a common ancestor recipe (type/super class), means that its very properties (fields and methods) can be expected in all sub classes (inherited/child recipes), in other words a generic "chocolate cake recipe" might be used to create two new specialized versions of a chocolate cake: "white chocolate cake" and "dark chocolate cake", where the color of the chocolate merely becomes an attribute that may be configurable using a chocolate cake specific method like "setChocolateColor()".
If you want your recipe to provide a way for new recipes to override some components of your recipe, you can provide boilerplate actions (methods) that can be individually overriden (virtual inheritance).
回答11:
objects (usually) have state, behaviour, and identity.
basic o-o programming principles are encapsulation, inheritance, and polymorphism.
basic o-o design principles are here: http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod
回答12:
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):
void printContactInfo(String name, String address, String phoneNumber) {
System.out.println(name + " lives at " + address + " and his/her phone number is + "phoneNumber");
}
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:
Person someguy = new Person("MatrixFrog", "123 Notareal Street", "555 5555");
someguy.printContactInfo();
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!"
回答13:
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.
回答14:
IMHO we must first get them interested in OOP before bombarding them with all the concepts in OOP. To make them get attracted towards OOP, explaining all the concepts in OOP or showing examples of cats and dogs will not work. You need to show them the advantages by comparing a problem solved the OOP and the non OOP way. Make sure you solve the problem first the non OOP way, highlight the disadvantages, use one of the concepts of OOP to solve it. It might probably employ only one concept of OOP, but if you are able to make them feel the advantage it holds over the other method, they would themselves be eager to explore more of OOP. You just need to point them in the right direction after that. Once they are familiar with the concepts, point them towards design pattern books like "Head first design patterns".
回答15:
To a beginner: An object is like a noun. If you're in a classroom then you have desks, students, teacher, projector etc. Each has characterists of their own and some commonalities.
So if we wanted to write a program that would behave in the same way as a classroom, we need to recreate all these 'nouns' in code. Each can do things (student::listen()) and they can interact with each other (student::search(new Desk()))
When we have defined all the rules and behaviours (i.e written our classes/interfaces) then we set them loose in the program. for(i=0;i<30;i++){class.Add(new Student()))} etc
回答16:
My experience as a self-learner is that I introduced a fair amount of trouble in my head with the concept of object as mapped to a "real entity" like animals and cars and so on. It forms your head in willing to find a realistic (as in "the real world") taxonomy in your business objects even when there's none, and it confuses you in finding unrealistic taxonomical classification that are instead useful for real OO design (eg. design patterns). Finally, it pushes you to the point that you fossilize in one "real world" taxonomy even if other "less real world" can exist and they are better.
In any OOP book you find that a square is a kind of rectangle, and so a square is represented as inherited by a rectangle, but we know that this approach is deeply flawed (I read a paper on that, don't remember where, but you can search about the "fragile base class problem" in google). Also, in some programming languages, you don't need OO taxonomy for interface inheritance (see my post on this regard).
So, my suggestion is: present it but be very careful how far you go, and eventually switch immediately from the "car and animals" examples to a less nice to present taxonomy. You can deeply flaw their understanding if you push it too far.
回答17:
Stick with Booch's definition: An object has state, exhibits some well-defined behavior, and has a unique identity. I noticed that others posted this already, but people made comments regarding some objects not needing state, behavior, or identity which I disagree with. An object has state in the sense that some programmer defined amount of memory has been allocated for it, behavior in the sense that it can react to messages being sent to it, and identity in the sense that it can be assigned an identifier. Which actually sounds a lot like Kay's explanation of a lot of little specialized computers communicating with one another.
I also agree with the few posts that mention first understanding the concepts of procedural programming, because the work in an object-oriented program is still done at the procedure level. The difference is the level of abstraction at which the programmer can write the program. In object-oriented programming, programming at a higher level of abstraction is the ability for the programmer to make concepts that span state and behavior, in any combination, explicit. Which obviously requires an understanding of how to implement concepts using state and behavior.
The next major concept I would tackle is generalization. An object choosing which behavior to invoke in response to being sent a message, at run time, is what allows for generalization. Generalization occurs when a programmer hides the details of how to accomplish a similar concept in two distinct ways behind one uniform message.
From here I would move on to encapsulation, inheritance, and polymorphism. And from there on to more high level concepts. I just feel that keeping everything focused specifically around how these concepts help you solve problems is important for retaining them.
回答18:
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.
回答19:
I prefer using real-life examples that you can actually interact with: a dish-washer, a car, ...
These things also happen to have a very strict interface: a car (in Europe :)) has an Acceleration pedal, a Break and a Clutch. You can ask for it's current speed.
Encapsulation: no need to know how the engine works if you know the interface. A good thing that you don't have to tinker the engine yourself, too.
Polymorphism: you can drive a Lada and a Porche using the same interface. This means you are a polymorphous driver :).
Note: it's taken me years to differentiate the concept of an interface from inheritance. I would say: leave inheritance out for a while: most of the time code reuse is achieved better by composition (though that's a whole other discussion).
回答20:
Use real life examples.
- Animal (interface)
- Mammal (abstract class)
- Dog (class)
- Your dog (object instance)
access levels:
And your mom can't touch your privates, but your friends can.
回答21:
Start with explains what Object-Oriented-Design means...
- It means that you take a real-life situation you want to model using software and copy its model into a software models.
Each entity within the actual situation (the one that exists even if there was no software) gets a representative in the software's design - an object. (Abstraction)
Each kind of entity is a class, every entity of the same kind is an object of the same type.
* Give an example here from a field that interests your students and continue with same example.
- Try to make it a funny one.
Each object should model only one entity and that entire entity, if you change one object it should not affect another. (Encapsulation)
Next, you think of the relationships between the entities, is one a specific type of another (inheritance), is one a part of another (composition), can one go in and out of another (aggregation).
Next, you think about the main things the entities do (methods) and how to define them (properties/fields).
Now take an example for inheritance from the example you gave earlier and explain polymorphism - you can do the same thing that you can on the general type as you can on any specific type that inherits it and you can ask every specific type to do what you can ask the generic type to do, but they can do it whatever way they want to (overriding).
Next interfaces, here perhaps use animals - not all animals have tails to wag, but some do.
You want to model a man, a dog, a cat, a spider and a dinosaur. All are (or were) animals but the generic type - animal can't wag its tail, a. because there is no such thing as a generic animal (it's abstract) b. because not animals can WagTail().
However, all those that can WagTail() can implement the interface IWagTailable.
Access levels:
if something is part of an entities description or known actions (if it is in its contract) - it's public.
If an object keeps some information that only it needs to know about or is allowed to know about or does something no one knows about - it's private.
If not everyone is allowed to know about it but its inheritors are allowed to know about it - it's protected.
Maybe get into constructors (how to initialize the object's definitions) and destructors (freeing the memory/file handles/connections it's holding).
Maybe also properties - kind of like fields, only you can limit access to read-only, write-only or even make something happen when reading or writing.
回答22:
I prefer to think of Ants - it gives visual learners something to "see" and you "tell" for the auditory learners. Focus on the WHY for each part first to avoid the glassy eyes.
Ant derives from Insect (Inheritance)
Worker Ant, Queen Ant, Drone Ant all derive from Ant (Inheritance). There is no generic “Ant”, all ants are from the derived classes of Worker, Queen etc but they all have the same basic Interface –actions (methods) and Properties.
Worker Ant, Queen ant, Drone Ant derive from Ant and thus exhibit ad-hoc polymorphism where they all derive from the same Ant class and exibit subtyping polymorphism (Inheritance) of the Ant class, these ants are all a subclass of the Ant class and inherit the 6 legs, 2 eyes, 3 body segments etc. of the Ant – the Properties. Ant also has methods, walk, see, and grab ability of the Ant class. Thus the appplication of the implimentation of the Interface of the more generic Ant class (Polymorphism) with the properties and methods of the basic Ant class, but each subclass defines how it implements those.
Worker Ants have different activities and behavior. They Gather food, Protect colony, Dig tunnels, Care for Queen Ant etc but still have the base attributes of Ant (Interface). Jaws are used in each behavior - polymorphic function which is NOT Polymorphism in itself and thus you get the idea of, method overloading for the different use of the Jaws – each method has basic similarity (jaws, grab) but different object types are used – grab dirt, grab other ant, grab food, grab gunk off queen, grab enemy. This shows a WHY of overloading methods, - areas of specialization depending upon what is grabbed – larva (young ants) and food are handled gently and differently than the enemy where we want to rip them up.
Each Worker Ant is an Instance of an ant, separate but with similar behaviors and different task/state at a given time, so given the tasks, they can be on different threads. If one ant on a food-gathering mission (thread) dies, the other ants keep seeking food, as they are not dependant on the dead ants survival.
Each Ant has access and ability to manipulate its own Private attributes, legs, eyes and so forth, but not to manipulate other ants eyes and legs (Access Levels).
Ant Colony – the overall namespace for the Ant – thus the Queen Ant and Worker Ant might belong to the Ant Colony namespace, and the worker ants have access to the Queen Ant but nothing outside does (Protected)
Queen ants never go outside normally – (Access Levels)
Each Ant has access and ability to manipulate its own attributes, legs, eyes and so forth, but not to manipulate other ants eyes and legs (Access Levels). Now this ant knows where its legs are, where it is looking, those are Encapsulated within its instance. The act of Encapsulation creates Abstraction to some degree here.
By using the concept of Encapsulation we can Abstract and thus we can send the Worker Ant off to get food, but we do not have to care how the ant gets the food, only that it returns with food, we have isolated the details of the activity from the result.
You can impliment the examples in the language of choice for your audience.
If this helps one person, I am satisfied :).
I hope I have not confused myself :)
回答23:
From my own experience, I think the idea of an object or class merely being an instance of a thing or a description of a thing can be quite adequate for an initial abstraction. What the thing has, i.e. members and/or properties, and can do, i.e. methods, are the next level of things to add. Then comes the inheritance, abstraction, encapsulation and polymorphism ideas as ways to round out the initial take of modelling that OOP tries to do. I came to OOP from a procedural coding background so the idea of customizable variable types does create a lot of different ideas that can be explored.
回答24:
I would use one example through the whole thing to build up the concept instead of jumping over unrelated examples.
That magical example would be GUI.
GUI made a lot of sense when I understood OOP after a lot of struggle.
A window is an 'object'. a button is nothing but a fancy way to say a rectangle drawn in a special way (abstraction). A window 'has' buttons. A hyperlink label 'is' a button. every Clickable thing on my Screen is a button (Interfaces). All buttons when clicked go to Stack overflow (inheritance). Except one button, which goes to Server fault (polymorphism).
And the hard part, 'Encapsulation' which is nothing but a fancy way to save the programmer from debugging :)
In the end I would stress that OOP is not the end of the world, If it does not make sense to
think about something as an Object then it is NOT an Object. Because I have seen a programmer trying to build a mergesort class :D
Thanks,
回答25:
I would try to compare the procedural programming paradigm with the OOP one. Even if your students are completely new to programming, I would show them some examples with 'primitives' and then the examples with objects. I would point the difference between a variable of a primitive type and an object of a class in that the type of the object may contain a number of variables (members). Of course at that point you should have mentioned functions, if they didn't already know them. In fact, in lesson one, I would explain the basic concepts of procedural programming (variables, types, functions) that are the basis for the fundamental concepts of OOP. After all, OOP is just a wrapper for procedural programming in itself.
After lesson one, along with explaining members of an object, you should explain methods as well. For "really junior students" I would focus on access levels, encapsulation and lastly on inheritance.
The real world examples, like car etc. can be used to show why it is good to have objects, but after exposing your students to the basic programming concepts. For your more talented students I would give out hints, like that an object is just an implicit argument to its methods, or that a member of an object is like a restricted global variable, or that an object is like a closure, etc. (that depends of course on your students and you need to make sure not to confuse them, so this last piece of advise is optional, of course :-) ).
回答26:
I might start with anonymous types or something like JSON to demonstrate that objects are just collections of properties. Talk about cohesion.
What if we want a bunch of these objects? Classes/constructors/instances.
What about functionality? Methods.
Then demonstrate the problems that occur from a lack of encapsulation. Show how getters/setters/private fields alleviate the problem (maybe move to a typed language if you've been using JSON)...
Then show how inheritance allows code reuse--maybe show a sample of inheritance by actually re-typing (with the keyboard) the functionality to demonstrate what a pain it is. Show that you can change something in one authoritative place when things are well-designed.
Then introduce polymorphism--because inheritance is sometimes insufficient. Include interfaces here.
Try to use real-world examples--either from the code-base they'll be working on or from your own portfolio. As you go, demonstrate refactoring and other good practices. "Hey, I keep repeating this pattern--I should consolidate it somehow".
回答27:
this question is interesting ... and very complicated ... because it depends on the language you use ...
take objective-c: an object has
it's variables, only accessible from
inside, and methods, such as
accessors ... objective-c actually
sends around messages between
objects ... which gives comes at a
certain cost, but allows lots of cool
things, like proxies, mock objects,
profiling, AOP and so forth ... in
objective-c, a class is an object ...
objective-c does not have the notion
of access levels ...
take PHP ... there, classes are not
objects ... objects have variables
and methods ... and it's totally
inconsistent ... :) ... just as a bad example ...
take Ruby ... there, everything is
completely dynamic ... an object has
its variables, only visible from
inside, and a class, determining its
methods ... you can modify that class
at runtime, or even, you can assign a
different class to that very object
... funky ... and also, in ruby,
operators are methods of objects
... you have incredible language
constructs like blocks ...
take ECMA-Script(JavaScript for example) ... here everything is an object ... functions
are first class objects ... an object
has a set of properties (fully
dynamic), some of which may be
functions, acting as the object's
methods ... you may take the method
of one object, and apply it to
another instead (does not necessarily
make sense, but it is feasible) ...
any function may be used, to
instantiate a new object ... and so
on ... ECMA-Script does not have the
concept of access levels, but you can
hide away data using closures, if
necessary ... ECMA-Script does not
know classes ... but inheritance is
achieved through its prototype based
nature ...
i could go on ... but you see my point, i guess ... many languages implement only parts of all the things that most understand as OOP and emphasize different things ... sometimes it's a weakness, sometimes powerfull ... also the semantics, of what an object is, and what a method is, is VERY different ... to not confuse your students, you should really stick to one language, or languages having exactly the same semantics, when it comes to objects, and the describe what an object is ... otherwise, they will never actually understand you model ... once they got their head around it, you can show, how OOP looks in other languages ...
i think, you should take JavaScript or Ruby (although i think JavaScript is better, and then move on to ActionScript 2, to have a typed version of it, and classes, interfaces etc. ... or start with ActionScript 2 directly), to show concepts of OOP, since they are very radical, clear and simple ... or maybe other scripting languages ...
a thing not to forget is, that it's object oriented and not class oriented programming ... chosing a language, that does not need classes in order to have objects, seems a good idea ...
- introduce objects as entities ... first just create some anonymous dynamic objects, give them some attributes and methods and play around ... maybe fiddle around with some built-in global objects, if any such things exist ... try to show, how thes objects can model a real world ... don't try to hard ... simple examples ... let them add a few methods on the run and experiment a bit ...
- once they get a hang of it and really
kind of understand what objects are,
explain, what a type is, first on the
builtin types (if you choose the
right language, any value is an
object ... i think that's a good way
to go) ... then explain, what a class
is ... an object, or maybe just a
language construct, to create
objects, that are similar and have
the same type ... then explain
subclassing ... don't inherit car from vehicle ... don't extend fruit with apple
... it's confusing ... you have a
type of objects, and you have
subtypes of that type ... as in real
life, science, maths ... anything ...
- then explain interfaces ... as a different kind of types, that categorize an object not by where it comes from, but by what it does ...
- once that is really understood, talk about encapsulation and access levels
- once they understood inheritance and interfaces,
tell them, inheritance is cool for not writing a lot, but it does not solve all problems ... emphasize the importance of interfaces ... teach them to use interfaces as parameter types, whenever possible ... introduce composition, forwarding, proxying, delegation, etc. ... show them how nicely factories can be used to reduce dependancies on concrete classes ...
- preach decoupling, and teach them ways to achieve this ... explain them, how to build their object hierarchies, so they don't wind up with a chaotic network, instead of a nice tree, where dependancies get ever smaller, as you go to the leaves ...
- now you can safely move to languages, that are less sexy, but more mature ...
use a language, that is consistent and keeps code short and concise ... try to avoid situations, where you have n lines of code, that are mandatory, but you don't really have the time to explain them ...
in my opinion, introducing people to OOP first, is a good decision ... OOP is about modelling ... the higher the language, the more it teaches abstract thinking ... starting with procedural languages, where you maintain states in tons of variables scattered around your programm, is not good ... it takes a hell lot of time for people who really learned procedural programming, to move on to OOP ...
well, this was a little more, than i actually inteded to write ... hope it helps at least ... :)
greetz
back2dos