Have you ever structured your source code based on your user interface parts? For example if your UI consists of:
GridView for showing some properties
3D rendering panel
panel for choosing active tools
, then you name and group your variables and functions more or less in the following way:
class Application
{
string PropertiesPanel_dataFile;
DataSet PropertiesPanel_dataSet;
string[] PropertiesPanel_dataIdColumn;
void PropertiesPanel_OpenXml();
void PropertiesPanel_UpdateGridView();
string ThreeDView_modelFile;
Panel ThreeDView_panel;
PointF[] ThreeDView_objectLocations;
void ThreeDView_RenderView();
string ToolPanel_configurationFile;
Button[] ToolPanel_buttons;
void ToolPanel_CreateButtons();
}
What's your opinions on this? Can this architecture work in long run?
PS. Even though this solution might remind you of Front-ahead-design april-fool's joke http://thedailywtf.com/Articles/FrontAhead-Design.aspx my question is serious one.
EDIT
Have been maintaining and extending this kind of code for half a year now. Application has grown to over 3000 lines in the main .cs file, and about 2000 lines spread out in to smaller files (that contain generic-purpose helper-functions and classes). There are many parts of the code that should be generalized and taken out of the main file, and I'm constantly working on that, but in the end it doesn't really matter. The structure and subdivision of the code is so simple, that it's really easy to navigate though it. Since the UI contains less than 7 major components, there's no problem in fitting the whole design in you head at once. It's always pleasant to return to this code (after some break) and know immediately where to start from.
I guess one the reasons this gigantic procedural-like structure works in my case is the event-like nature of UI programming in c#. For the most part all this code does is implementation of different kinds of events, that are really specific to this project. Even though some event-functions immediately grow into couple of pages long monsters, coupling between event-handlers is not that tight, so it makes it easier to refactor and compress them afterwards. That's why Iam intentionally leaving generalization and refactoring for later time, when other projects start to require the same parts of implementation that this project uses.
PS to make it possible to navigate through 3000 lines of code I'm using FindNextSelection- and FindPrevSelection-macros in visual studio. After left-clicking on some variable I'm pressing F4 to jump to the next instance of it, and F2 to the previous instance. It's also possible to select some part of variable name and jump between partial-name matches. Without these shortcuts I would most defenetly lost my way long time ago :)
That looks very procedural in concept and is completely bypassing the value of OOD. The sensible approach would be to create objects for each of your elements and the values you have given would be properties of those objects, i.e.
class PropertiesPanel
{
public string DataFile { get; set; }
public DataSet DataSet { get; set; }
public string[] DataIDColumn { get; set; }
etc...
I think you get the idea so I'm not going to type the whole lot out. That's a first stage and there may be further work you could do to structure your application appropriately.
The best advice I ever received for OOD was to look to the smallest object that each logical branch of your app can be distilled to, it probably on has native types for properties (with .NET there no point in reinventing Framework objects either so they can be in your base class) and then using inheritance, polymorphism and encapsulation to expand on those base classes until you have an object that encapsulates the logical branch.
At the time I was writing an app that pushed data to an I2C device so I started with a class that put a bit onto an I2C bus, that was inherited by a class that put a byte onto a bus, inherited by a class that put an array of bytes onto the bus, and finally a class that put an address and an array of bytes. This is rather extreme OOD but it produced very clean code with each class being very small and very easy to debug.
It's possibly more work up front in thinking about the problem but in the long run it save soooooo much time it's just not funny.
It's OK to structure your user interface code based on your UI parts, but the non-UI related logic of your program should be kept separate.
But event on the UI part you shouldn't just smash everything into one class. Instead you should divide your UI code into several classes, so that every class only deals with one UI component and doesn't deal with others it doesn't need to know about:
class Application
{
PropertiesPanel
ThreeDView
ToolPanel
}
class PropertiesPanel {
string dataFile;
DataSet dataSet;
string[] dataIdColumn;
void OpenXml();
void UpdateGridView();
}
class ThreeDView {
string modelFile;
Panel panel;
PointF[] objectLocations;
void RenderView();
}
class ToolPanel {
string configurationFile;
Button[] buttons;
void CreateButtons();
}
What's your opinions on this?
It’s a mess.
Can this architecture work in long
run?
No. (At least not without a lot of sweat.)
The names are insanely verbose. If you think about it, the long name prefixes are there to create a kind of separate ‘namespace’, to group related things together. There already is a better language construct for this very kind of thing – it’s classes. But the main problem is elsewhere.
User interfaces change often, concepts change seldom. If your code structure mirrors the user interface, you are locked to this particular interface. This makes reusing and refactoring the code quite hard. If you structure the code around the base concepts from the problem domain, you have a better chance to reuse already existing code as the software develops – the design will adapt to changes. And changes always happen in software.
(I hope that the ‘base concepts from the problem domain’ part is clear. For example, if you create a system for a local theater, you should base your design on the concepts of a Movie, Visitor, Seat, and so on, instead of structuring it around MovieList, SeatMap, TheaterPlan and such.)
Most of the time it is a good idea to decouple the core code from the GUI as much as possible (This is exactly what the Model–View–Controller design system is all about.) It is not an academic excercise, nor it is only required if the interface is going to change. A great example of decoupling the GUI from the rest of the code is the GUI programming on Mac OS X, with the Interface Designer, bindings and such. Unfortunately it takes a while to get into, you cannot simply skim the docs on the web and be enlightened.
Related
I am trying to understand the separation of concerns used within AOP. Therefore i would appreciate if someone could explain me what does mean code scattering and code tangling in AOP using some basic HelloWorld examples. How would i know afterwards if a given concern is not a system-core concern but rather an aspect? Many thanks.
I'm afraid I'll use logging as an example, which is the one we always use, but I hope it makes it easy to understand. Consider this helloworld program with logging:
public class HelloWorld {
private static Logger logger = Logger.getLogger(HelloWorld.class);
public static void main(String []argv) {
logger.entering("HelloWorld","main");
System.out.println("Hello World");
logger.exiting("HelloWorld","main");
}
}
My class only has 8 lines (ignoring whitespace) - 3 of them are logging, almost half! Logging has nothing to do with the primary goal of this class which is to print Hello World. Logging is tangled up with the primary goal of this class. If we could remove it and express it another way then we'd have half the code and what the class is primarily trying to achieve would be even clearer. Additionally being tangled up may harm capabilities like reuse - this code can't be used to print helloworld without it doing some logging and needing some kind of logging infrastructure around.
Now consider a real system where there are multiple classes, and they are all doing logging. Now suppose I decide I want to change one of the logging methods I'm using - I want all my calls to entering changed to info and to include some extra information. Nightmare! My logging is scattered across my codebase. There isn't one place to make this change, there might be thousands.
If I captured that scattered, crosscutting concern in an aspect, there would be just one place to make the change.
Identifying what might be an aspect:
consider the primary function of your classes - what are they fundamentally being built for. Is there other code in there that isn't strictly related to that, but you find you are needing to do it (e.g. begin and commit a transaction, authenticate with some security service).
do you find yourself doing a very similar thing over and over - either across multiple classes or even just over multiple methods within one class.
Scattering can be a small scale concern. Maybe every method in one of your classes is repeating some pattern, but no other classes are using it. No harm in creating a small aspect for the class that just addresses the scattering within those methods.
I don't really understand why it's generally good practice to make member variables and member functions private.
Is it for the sake of preventing people from screwing with things/more of an organizational tool?
Basically, yes, it's to prevent people from screwing with things.
Encapsulation (information hiding) is the term you're looking for.
By only publishing the bare minimum of information to the outside world, you're free to change the internals as much as you want.
For example, let's say you implement your phone book as an array of entries and don't hide that fact.
Someone then comes along and writes code which searches or manipulates your array without going through your "normal" interface. That means that, when you want to start using a linked list or some other more efficient data structure, their code will break, because it's used that information.
And that's your fault for publishing that information, not theirs for using it :-)
Classic examples are the setters and getters. You might think that you could just expose the temperature variable itself in a class so that a user could just do:
Location here = new Location();
int currTemp = here.temp;
But, what if you wanted to later have it actually web-scrape information from the Bureau of Meteorology whenever you asked for the temperature. If you'd encapsulated the information in the first place, the caller would just be doing:
int currTemp = here.getTemp();
and you could change the implementation of that method as much as you want. The only thing you have to preserve is the API (function name, arguments, return type and so on).
Interestingly, it's not just in code. Certain large companies will pepper their documentation with phrases like:
This technical information is for instructional purposes only and may change in future releases.
That allows them to deliver what the customer wants (the extra information) but doesn't lock them in to supporting it for all eternity.
The main reason is that you, the library developer, have insurance that nobody will be using parts of your code that you don't want to have to maintain.
Every public piece of your code can, and inevitably will get used by your customers. If you later discover that your design was actually terrible, and that version 2.0 should be written much better, then you realise that your paying customers actually want you to preserve all existing functionality, and you're locked in to maintaining backwards compatibility at the price of making better software.
By making as much of your code as possible private, you are unreservedly declaring that this code is nobody's business and that you can and will be able to rewrite it at any time.
It's to prevent people from screwing with things - but not from a security perspective.
Instead, it's intended to allow users of your class to only care about the public sections, leaving you (the author) free to modify the implementation (private) without worrying about breaking someone else's code.
For instance, most programming languages seem to store Strings as a char[] (an array of characters). If for some reason it was discovered that a linked list of nodes (each containing a single character) performed better, the internal implementation using the array could be switched, without (theoretically) breaking any code using the String class.
It's to present a clear code contract to anyone (you, someone else) who is using your object... separate "how to use it" from "how it works". This is known as Encapsulation.
On a side note, at least on .NET (probably on other platforms as well), it's not very hard for someone who really wants access to get to private portions of an object (in .NET, using reflection).
take the typical example of a counter. the thing the bodyguard at your night club is holding in his hands to make his punch harder and to count the people entering and leaving the club.
now the thing is defined like this:
public class Counter{
private int count = 0;
public void increment()
{
count++;
}
public void decrement()
{
count--;
}
}
As you can see, there are no setters/getters for count, because we don't want users (programmers) of this class, to be able to call myCounter.setCount(100), or even worse myCounter.Count -= 10; because that's not what this thing does, it goes up one for everyone entering and down for everyone leaving.
There is a scope for a lot of debate on this.
For example ... If a lot of .Net Framework was private, then this would prevent developers from screwing things up but at the same time it prevents devs from using the funcionality.
In my personal opinion, I would give preference to making methods public. But I would suggest to make use of the Facade pattern. In simple terms, you have a class that encapsulates complex functionality. For example, in the .net framework, the WebClient is a Facade that hides the complex http request/response logic.
Also ... Keep classes simple ... and you should have few public methods. That is a better abstraction than having large classes with lots of private methods
It is useful to know how an object s 'put together' have a look at this video on YouTube
http://www.youtube.com/watch?v=RcZAkBVNYTA&list=PL3FEE93A664B3B2E7&index=11&feature=plpp_video
Our architect has spoken about using SOA techniques throughout our codebase, even on interfaces that are not actually hosted as a service. One of his requests is that we design our interface methods so that we make no assumptions about the actual implementation. So if we have a method that takes in an object and needs to update a property on that object, we explictly need to return the object from the method. Otherwise we would be relying on the fact that Something is a reference type and c# allows us to update properties on a reference type by default.
So:
public void SaveSomething(Something something)
{
//save to database
something.SomethingID = 42;
}
becomes:
public Something SaveSomething(Something something)
{
//save to database
return new Something
{
//all properties here including new primary key from db
};
}
I can't really get my head around the benefits of this approach and was wondering if anyone could help?
Is this a common approach?
I think your architect is trying to get your code to have fewer side effects. In your specific example, there isn't a benefit. In many, many cases, your architect would be right, and you can design large parts of your application without side effects, but one place this cannot happen is during operations against a database.
What you need to do is get familiar with functional programming, and prepare for your conversations about cases like these with your architect. Remember his/her intentions are most likely good, but specific cases are YOUR domain. In this case, the side effect is the point, and you would most likely want a return type of bool to indicate success, but returning a new type doesn't make sense.
Show your architect that you understand limiting side effects, but certain side effects must be allowed (database, UI, network access, et cetera), and you will likely find that he or she agrees with you. Find a way to isolate the desired side effects and make them clear to him or her, and it will help your case. Your architect will probably appreciate it if you do this in the spirit of collaboration (not trying to shoot holes in his or her plan).
A couple resources for FP:
A great tutorial on Functional
Programming
Wikipedia's entry on Functional programming
Good luck, I hope this helps.
I understand the differences between them (at least in C#). I know the effects they have on the elements to which they are assigned. What I don't understand is why it is important to implement them - why not have everything Public?
The material I read on the subject usually goes on about how classes and methods shouldn't have unnecessary access to others, but I've yet to come across an example of why/how that would be a bad thing. It seems like a security thing, but I'm the programmer; I create the methods and define what they will (or will not) do. Why would I spend all the effort to write a function which tried to change a variable it shouldn't, or tried to read information in another class, if that would be bad?
I apologize if this is a dumb question. It's just something I ran into on the first articles I ever read on OOP, and I've never felt like it really clicked.
I'm the programmer is a correct assumption only if you're the only programmer.
In many cases, other programmers work with the first programmer's code. They use it in ways he didn't intend by fiddling with the values of fields they shouldn't, and they create a hack that works, but breaks when the producer of the original code changes it.
OOP is about creating libraries with well-defined contracts. If all your variables are public and accessible to others, then the "contract" theoretically includes every field in the object (and its sub-objects), so it becomes much harder to build a new, different implementation that still honors the original contract.
Also, the more "moving parts" of your object are exposed, the easier it is for a user of your class to manipulate it incorrectly.
You probably don't need this, but here's an example I consider amusing:
Say you sell a car with no hood over the engine compartment. Come nighttime, the driver turns on the lights. He gets to his destination, gets out of the car and then remembers he left the light on. He's too lazy to unlock the car's door, so he pulls the wire to the lights out from where it's attached to the battery. This works fine - the light is out. However, because he didn't use the intended mechanism, he finds himself with a problem next time he's driving in the dark.
Living in the USA (go ahead, downvote me!), he refuses to take responsibility for his incorrect use of the car's innards, and sues you, the manufacturer for creating a product that's unsafe to drive in the dark because the lights can't be reliably turned on after having been turned off.
This is why all cars have hoods over their engine compartments :)
A more serious example: You create a Fraction class, with a numerator and denominator field and a bunch of methods to manipulate fractions. Your constructor doesn't let its caller create a fraction with a 0 denominator, but since your fields are public, it's easy for a user to set the denominator of an existing (valid) fraction to 0, and hilarity ensues.
First, nothing in the language forces you to use access modifiers - you are free to make everything public in your class if you wish. However, there are some compelling reasons for using them. Here's my perspective.
Hiding the internals of how your class operates allows you to protect that class from unintended uses. While you may be the creator of the class, in many cases you will not be the only consumer - or even maintainer. Hiding internal state protects the class for people who may not understand its workings as well as you. Making everything public creates the temptation to "tweak" the internal state or internal behavior when the class isn't acting the way you may want - rather than actually correcting the public interface of internal implementation. This is the road to ruin.
Hiding internals helps to de-clutter the namespace, and allows tools like Intellisense to display only the relevant and meaningful methods/properties/fields. Don't discount tools like Intellisense - they are a powerful means for developers to quickly identify what they can do with your class.
Hiding internals allows you to structure an interface appropriate for the problem the class is solving. Exposing all of the internals (which often substantially outnumber the exposed interface) makes it hard to later understand what the class is trying to solve.
Hiding internals allows you to focus your testing on the appropriate portion - the public interface. When all methods/properties of a class are public, the number of permutations you must potentially test increases significantly - since any particular call path becomes possible.
Hiding internals helps you control (enforce) the call paths through your class. This makes it easier to ensure that your consumers understand what your class can be asked to do - and when. Typically, there are only a few paths through your code that are meaningful and useful. Allowing a consumer to take any path makes it more likely that they will not get meaningful results - and will interpret that as your code being buggy. Limiting how your consumers can use your class actually frees them to use it correctly.
Hiding the internal implementation frees you to change it with the knowledge that it will not adversely impact consumers of your class - so long as your public interface remains unchanged. If you decide to use a dictionary rather than a list internally - no one should care. But if you made all the internals of your class available, someone could write code that depends on the fact that your internally use a list. Imagine having to change all of the consumers when you want to change such choices about your implementation. The golden rule is: consumers of a class should not care how the class does what it does.
It is primarily a hiding and sharing thing. You may produce and use all your own code, but other people provide libraries, etc. to be used more widely.
Making things non-public allows you to explicitly define the external interface of your class. The non-public stuff is not part of the external interface, which means you can change anything you want internally without affecting anyone using the external interface,
You only want to expose the API and keep everything else hidden. Why?
Ok lets assume you want to make an awesome Matrix library so you make
class Matrix {
public Object[][] data //data your matrix storages
...
public Object[] getRow()
}
By default any other programmer that use your library will want to maximize the speed of his program by tapping into the underlying structure.
//Someone else's function
Object one() {data[0][0]}
Now, you discover that using list to emulate the matrix will increase performance so you change data from
Object[][] data => Object[] data
causes Object one() to break. In other words by changing your implementation you broke backward compatibility :-(
By encapsulating you divide internal implementation from external interface (achieved with a private modifier).
That way you can change implementation as much as possible without breaking backward compatibility :D Profit!!!
Of course if you are the only programmer that is ever going to modify or use that class you might as well as keep it public.
Note: There are other major benefits for encapsulating your stuff, this is just one of many. See Encapsulation for more details
I think the best reason for this is to provide layers of abstraction on your code.
As your application grows, you will need to have your objects interacting with other objects. Having publicly modifiable fields makes it harder to wrap your head around your entire application.
Limiting what you make public on your classes makes it easier to abstract your design so you can understand each layer of your code.
For some classes, it may seem ridiculous to have private members, with a bunch of methods that just set and get those values. The reason for it is that let's say you have a class where the members are public and directly accessible:
class A
{
public int i;
....
}
And now you go on using that in a bunch of code you wrote. Now after writing a bunch of code that directly accesses i and now you realize that i should have some constraints on it, like i should always be >= 0 and less than 100 (for argument's sake).
Now, you could go through all of your code where you used i and check for this constraint, but you could just add a public setI method that would do it for you:
class A
{
private int i;
public int I
{
get {return i;}
set
{
if (value >= 0 && value < 100)
i = value;
else
throw some exception...
}
}
}
This hides all of that error checking. While the example is trite, situations like these come up quite often.
It is not related to security at all.
Access modifers and scope are all about structure, layers, organization, and communication.
If you are the only programmer, it is probably fine until you have so much code even you can't remember. At that point, it's just like a team environment - the access modifiers and the structure of the code guide you to stay within the architecture.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 years ago.
Improve this question
My relative is studying programming and has a hard time understanding classes. He has trouble understanding for example that you need to instantiate it, that methods cannot access variables in other methods and if you change a variable in one instance of a class it doesn't change for other instances.
I've tried to use analogies like a class definition is like a blueprint of a house. And instances are houses made from that blueprint.
How do you explain classes and OO in general?
Seriously use Animals, it works great. And that's what nailed the concept for me years ago. Just found this C# code. It seems good
// Assembly: Common Classes
// Namespace: CommonClasses
public interface IAnimal
{
string Name
{
get;
}
string Talk();
}
// Assembly: Animals
// Namespace: Animals
public class AnimalBase
{
private string _name;
AnimalBase(string name)
{
_name = name;
}
public string Name
{
get
{
return _name;
}
}
}
// Assembly: Animals
// Namespace: Animals
public class Cat : AnimalBase, IAnimal
{
public Cat(String name) :
base(name)
{
}
public string Talk() {
return "Meowww!";
}
}
// Assembly: Animals
// Namespace: Animals
public class Dog : AnimalBase, IAnimal
{
public Dog(string name) :
base(name)
{
}
public string Talk() {
return "Arf! Arf!";
}
}
// Assembly: Program
// Namespace: Program
// References and Uses Assemblies: Common Classes, Animals
public class TestAnimals
{
// prints the following:
//
// Missy: Meowww!
// Mr. Bojangles: Meowww!
// Lassie: Arf! Arf!
//
public static void Main(String[] args)
{
List<IAnimal> animals = new List<IAnimal>();
animals.Add(new Cat("Missy"));
animals.Add(new Cat("Mr. Bojangles"));
animals.Add(new Dog("Lassie"));
foreach(IAnimal animal in animals)
{
Console.WriteLine(animal.Name + ": " + animal.Talk());
}
}
}
And once he's got this nailed, you challenge him to define Bird (fly), and then Penguin (fly!?)
The best way I got it through to my wife (a chartered accountant) is as follows.
In 'regular' programming you have data (things that are manipulated) and code (things that manipulate) and they're separate. Sometimes you get mixed up because a certain piece of code tries to manipulate the wrong thing.
In my wife's case, I said a invoice arrived (which involves no physical money changing hands) and accidentally updated a bank balance, something she immediately saw as potential fraud (she used to do forensic accounting, everything is potential fraud to her, including most of my share trades :-).
You could just as easily say that a piece of code meant to wash a floor with a huge mop decided to do it with your toothbrush.
With OO programming, the manipulators and manipulatees are inextricably entwined. You don't apply the floor washing process to the floor, instead you command the floor to wash itself. It knows how to do this because the code is part of the object, not something external to it.
In the accounting case above, I think we ended up having the chart of accounts as the object and we told it to apply a invoice to itself. Since it understood the process, it knew which accounts were allowed to be updated (creditors liability account and an expense account if I remember correctly).
Anyway, that's irrelevant and I'm just meandering now. What I'm saying is to express it in terms your target audience will understand. I suppose that's the secret of most teaching.
Like all old farts, I'd like to answer this with a story from my own life.
I started programming basic on a VIC-20. Not knowing anything else, I though this was how all computers were programmed. I thought it was a bit hard to keep track of which variable names I had used and which were still free, (scope problem). I also thought it was hard to divide my program into repeatable chunks using gosub-return and setting and reading the variables that these would use, (lack of methods).
Then I got into Turbo C over MS-DOS. Now I could create my own methods and functions! I was no longer stuck with the old finite set of commands in basic. I felt like I was creating a new language for every program I wrote. C gave me more expressive power.
C++ was the first object oriented language I heard about. The big moment for me was when I understood that I could create my own data types, and even overload the operators. Again, it felt like I could create my own language containing both new functions and data types, complete with operators.
That's how I would sell OO to a new programmer. Explain that it gives expressive power because they can define their own data types. I always thought encapsulation was a better selling point than inheritance.
I assume the target knows how to use graphical user interfaces. I found the best way is to describe OOP with stuff that they are really used for. Say
Class
A Window is a class. It has methods like
Show a window
Enable a window
Set the window's title
A Window has attributes. That is data associated with it. It is encapsulated into the class, together with the functions that operate on them
A Window has dimensions. Width and height.
A Window has possibly a parent window, and possibly children.
A Window has a title
Object
There are many windows. Each particular window is an object of the class Window. A Parent window containing 10 windows makes 11 Window objects.
Deriveration
A Button is a Window. It has dimensions has a parent window and has a title, the label of a button. It's a special kind of a window. When you ask for a window object, someone can give you a Button. A Button can add functions and data that are specific for a button:
A Button has a state. It can be in a pressed state, and unpressed state.
A Button can be the default button in a Window.
While you are explaining OO with animals, do not forget to illustrate the "is-a" relationship with Stinger missiles-armed kangaroos ;-)
The kangaroos scattered, as predicted, and the Americans nodded appreciatively . . . and then did a double-take as the kangaroos reappeared from behind a hill and launched a barrage of stinger missiles at the hapless helicopter. (Apparently the programmers had forgotten the remove "that" part of the infantry coding).
The lesson? Objects are defined with certain attributes, and any new object defined in terms of the old one inherits all the attributes. The embarrassed programmers had learned to be careful when reusing object-oriented code, and the Yanks left with the utmost respect for the Australian wildlife.
Read the Java tutorials for some good ideas and real world examples.
How about "each molding is built using a mold", or "each model is built using a template", and so "each object is built using a class" ?
Note that it works for class-oriented OOP (which is what you want), but not for prototype-oriented OOP.
As for explaining OOP to a programmer, I'd add examples illustrating:
Separating state from behavior
Most of the time, an instance describe a state, and a class describe a behavior.
Delegation
An instance delegates its behavior to its class, and the class in turn can delegate its behavior to its superclasses (or mixins or traits)
Polymorphism
If class A inherits from class B, an instance of A can be used anywhere an instance of class B can be used.
Messages & methods
A message (or generic function, or virtual function) is like a question. Most of the time, several classes can answer to this question.
A corresponding method is a possible answer to the question, that resides in a class.
When sending a message to an instance, the instance looks up for a corresponding method in its class. If found, it calls it (with the instance bound to 'self' or 'this'. Otherwise, it looks for a corresponding method in its mixins, traits, or superclasses, and calls it.
If they're old enough to have ever filled out a tax form, show them a 1040EZ and explain that an instance of a class is like a filled-out form: each blank is a member variable of the object, and the form also includes instructions for what to do with the member variables, and those instructions are the member functions of the object. A class itself is like a master copy of the form, from which you can print off an endless number of blank forms to fill out.
One thing that I would counsel to AVOID in trying to communicate the concepts of OO to new programmers is using only examples where objects (in the OO sense) represent real-world physical objects. This will actually make students more confused when they encounter objects used to represent non-physical objects (such as a color scheme, or most of the behavioral patterns in "Design Patterns") or objects used just as a useful way to store related functions and related data in the same place (think Java's java.lang.Math for an example.)
Believe it or not, sports!
I've had success in teaching and mentoring by talking about the way that e.g. a play for a football team is described in terms of how the various positions (Center, Quarterback, Runningback, etc.) interact to accomplish a particular goal. In one version, the positions correspond to classes, and specific persons (Tony Romo, Johnny Unitas, etc.) are instances of the class -- individuals who exhibit the same behaviors as defined by the positions.
The second version of this metaphor is to explain that the positions may be interfaces (in the Java sense) rather than classes. An interface really represents a role fulfilled by any object that implements the methods of the interface. And it's perfectly reasonable for an object (via its class, in Java) to implement multiple interfaces, just as it is possible for a talented individual to play more than one position on a sports team.
Finally, the play is like a pattern, in that it describes how a set of roles interact to accomplish some specific goal.
An object is a black box, which you can't see through. Public methods are buttons on them. Protected methods are buttons hidden on the bottom, private methods are dip switches inside.
Let's see a washer as an object. We don't know how it works. We don't care if it's powered by natural gas, diesel, electricity, or plutonium. However, the mechanism and internal structure will vary greatly depending on the energy source like a combustion engine is needed for some. We don't care as long as if we push a "Wash" button, it washes our clothes.
Let's turn the washer not Object-oriented. Expose all the buttons by arranging them on the top. Customers can now turbo-charge the engine by tweaking some dip switches. Make the chassis transparent. Now, you can see your energy-saving washing machine is actually hybrid-powered. There are some monkeys in it. You free them into the wild, and the machine eats up your utility bill like a gas-guzzler.
Object-oriented programming is one technique of raising the level of abstraction by means of which the programmer communicates with the computer: from the level of flipping individual bits on and off, from the level of punching holes in paper cards, from the level of extraordinarily complex sequences of basic instruction codes, from the level of less complicated definitions of reusable templates for blocks of data and reusable blocks of code (structs and procedures), to the level of transcribing the concepts in the programmer's mind into code, so that what goes on inside the computer comes to resemble, for the programmer, what goes on outside the computer in the world of physical objects, intangible assets, and cause-and-effect.
the best book i've ever on object-oriented programming is Betrand's "Object-Oriented Software Construction" - if you really want to get the basics, there is no way around it.
I explain that procedural program is built around the "verbs" of the system, the things you want the system to do, whereas object-oriented programming is build about the "nouns," the things in the system, and what they are capable of, and that for many people this allows for a more straightforward mapping from the problem domain to software.
For the example, I use cars -- "Honda Accord" is a class, whereas the vehicle sitting in the parking lot is an object, an instance of a Honda Accord. A Honda Accord is a sedan, which is a car, which is an automobile, which is a motorized vehicle, which is a mode of transportation, etc. I cannot do anything with a car until I have a physical car to work with -- it doesn't help me that the idea of a Honda Accord exists.
It also helps for discussing interfaces and polymorphism -- the gas pedal means accelerate, regardless what the car does behind the scenes to make that happen. There are "private" parts of the car that I as user do not have access to -- I cannot directly apply an individual brake.
Since the issue is to explain to a new programmer and not to a mother or a wife, I would go right straight to the point. OO is about three main concepts:
Inheritance: a dog is an animal, parent-child, is-a relationship test, etc.
Encapsulation: public-private (protected), information hiding, internal underlying details are not important to the users of the class, protect users from future changes in the implementation.
Polymorphism: run-time binding, late binding, method that gets invoked depends on the type of the object and not the reference or pointer to the object.
Also, depending on how much the new programmer has been doing a procedural language, I would need to help him/her unlearn that the functions or procedures are no longer central.
Games are good.
There are gameobjects, from this walls, enemies and players inherit.
The gameobjects should be renderable have collision-logic etc. The enemies have ai-logic while the player is keyboard controlled.
Some UI-elements are also good, there are buttons, inputboxes etc that all inherit from some baseobject that has code for managing mouse-events etc.
I don't like the animal-example because i've never seen a "real" program that has ever had to use of animals in that way. It will only make people use inheritance all over the place and you will end up with cubes inheriting from rectangles that inherit from lines (why does so many books insist on using this as example? ).
OOP is a higher level of abstraction, a programmer can't really come to grasp it unless he has a good understanding of the normal (read: procedural) way of programming, and he must be able to write some programs that do something useful.
For me it took a series of several lectures by one of my university profs, where he discussed many theoretical aspects of programming, he tried to convince us that programming is about manipulating data, and that this data is a representation of the "state(s)" of the program, and some other abstract stuff that I forgot now! But the point is, it's hard to understand OOP without some theoretical abstract discussion first, and this discussion wouldn't make any sense to a person who hadn't had experience writing some real code.
After the theoretical discussion, you give an example of a moderately complex program, written in procedural style, and slowly convert it, step by step, into object oriented style. After the concrete example, you should go back to the theoretical discussion and just summarize the main points, directly relate the theoretical constructs to the concrete example, e.g you can talk about how the name, age, and salary of an employee represent his state.