OOP Story (For future Java Programmers)

I'm going to tell you a story to help you think about objects and how we deal with them.

Objects are electronic things. Electronic creatures. Critters.

They are active things. They can do stuff and they can remember stuff.

They can talk to other objects. Therefore they are more like people and cats than like rocks and trees.

You will probably find it advantageous to think of objects as if they were real rather than electronic. Thinking of them like people is a pretty good metaphor.

Just like people they are active. Just like people we can make requests of them. Just like people they themselves control what they do.

Most objects, though they can be active are pretty passive. They are only active when they are asked to do some specific thing. (couch potatoes).

Mostly what objects do is provide services to other objects. When one object is active, it might ask another object to perform a service--maybe asking it for a piece of information or to do some task.

When an object asks another for a service, the asker is taking a "client" role and the askee is taking the "server" role.

When a client asks a server to perform a service it waits (politely) until the server completes the request and then it resumes its own activity. This is most helpful when the server needs to return information to the client. It is also possible to arrange things so the client continues its activity instead of waiting, but this is less usual.

There are many kinds of objects in a "system". What kind of object a thing is determines what services it can provide. If you ask an object to do something that isn't appropriate, that is an error. In Java, the computer won't let that happen.

A "Program" is both a description of objects and the behavior that is allowed for each kind of object, and a description of what it is that we want the objects to actually do. The description of the objects must include descriptions of how they carry out their services.

To execute a program is to start with some object and ask it to do something, which asks other objects to do things, etc. until everything described in the program is done, or there is some error that prevents the program from continuing.

A "class" is that part of a program that is a description of a set of objects of the same kind. We sometimes say that the objects are in their class or that they have a class.

The class describes what an object in the class can do and also what it can remember, including who the objects can talk to.

Sometimes there will be only one object of a given class in a program and sometimes there will be several. When there are several of the same kind, they are especially friendly to one another. Sometimes they need to share information (or behavior) among themselves. For historical reasons, shared things are called static, since they are less dynamic than what goes on within each individual object.

Objects are things and so they have names that are used to refer to them. Some objects have many names (aliases) and some names are used at different times to refer to different objects. The most important kind of name that refers to objects is called a 'variable'. This is because who it refers to can vary as the program executes.

When we ask an object to perform a service, the request is called a message. A message can contain additional information called arguments (sometimes parameters) that help the server determine exactly what is wanted. These arguments can actually be objects, or perhaps simpler things.

For example "Doctor Jane Smith, I have a pain, right here (pointing to elbow)"

Here Doctor Jane Smith is a name. I have a pain is a message and the location is an argument.

We could use the alias "Doctor" for Doctor Jane Smith, or we could use the same "Doctor" to refer to another doctor.

When you ask an object to perform a service, the object and not the client determines exactly what will be done to fulfill the service. You wouldn't tell Dr. Smith how to heal you, just that she should do so. It is her responsibility to know how to perform the service.

Likewise, objects are in control of how they carry out services.

For example, when a professor asks a class of students to do a piece of homework, the professor becomes a "homework client" and each student becomes a "homework server." The professor (client) doesn't force the student (server) into any particular action, but expects that each student will "do the right thing" to fulfill the client-server contract. Indeed, each student will probably take a different approach to the assignment. What an individual student does depends on two factors: what kind of student he or she is, and what "state" the student is in at the time (lots of other assignments, state of health,...). Usually the professor will get back different results from each student, even when each is equally correct. But even when there is only one correct answer, and even when each student provides the correct answer, the process of arriving at the answer will probably be different for each student. The server and not the client is responsible for determining the correct sequence of actions to carry out the request. This is exactly the same in the object oriented programming world and is the basis of a deep concept called polymorphism.

The client in a system needs to know some name (reference) to a server to request a service. If we have a server object named doctor and a service named fixPain, then a message to the doctor might look like

doctor.fixPain(myElbow);

This assumes that the doctor (variable) actually refers to a doctor at the time. The client is whoever says this message.

Note that the server doesn't need to know who it is serving, but the client needs to know who the server is. This is like calling someone on the phone. When the caller (client) picks up the phone they know who they are calling. When the callee (server) picks up the phone they don't know who called. (No caller-ID in the object world.)

Usually in the real world, they know each other, but not necessarily in the object world. Sometimes we need to arrange that the server knows the client. This is usually the case when the receiver of a message needs to turn around and ask the sender for additional information. Then the original server becomes a client and the original client becomes a server. Frequent role changing is common in both the real world and the object world. One way to make change of roles possible is for the original client to give the original server some name or other reference by which a message can be sent back.

One of the things that needs to happen when a program executes, is that the objects need to be created. The best way to think of this is to believe that the class of an object knows how to create objects in that class. So that a class at runtime, is a factory for creating objects.

To create a new object in class Doctor, we might say Doctor

drSmith = new Doctor ("Jane Smith");

The new variable is called drSmith and the "new" before the class name causes the class to create a new "instance". "Jane Smith" is a special kind of object, known to Java, called a String. A String is a sequence of characters.

In Java classes are not objects, but it is useful to think of them as if they were. I think of them as factories for objects. a "new" expression is a message to the factory to create a new object of that class. Every object knows its own class and the class of an object never changes. "Static" things are part of the class, not part of objects created by the class.

We can then do things with the drSmith object.

Doctor myDoctor = drSmith;
myDoctor.fixPain(myElbow);

This assumes that myElbow is a name that refers to something at this point.

Here, myDoctor is a name that can refer to any Doctor and we make it refer to the object created above. We now have two names referring to the same newly created doctor object (alias).

Here a client is asking myDoctor to perform a service. The client is whichever object the above two "statements" appear within. The doctor receives the message and carries out the service. In doing so, the Doctor object may itself act as client to other objects asking them to perform some service for the doctor so that the doctor may carry out its function for the client. Thus, the doctor will need to talk to other objects that it knows about.

An object can even talk to itself, sending itself messages. This way, the server object can give names to things that it commonly does itself.

this.orderTests(xray);

or (a shorthand)

orderTests(xray);

If it isn't obvious from the above, classes also have names. Here Doctor is the name of a class and so is String. The string "Hello Class" doesn't have a name, but it could be given a name with":

String greeting = "Hello Class";

When we first introduce a name for an object we must tell its class. This is called "declaring" the name. We can give that name a referent at that time or not.

String someWords;

Here someWords is a name for a string, but doesn't refer to any string. We could make it do so at another point in the program, with

someWords = "These are the times that try men's souls.";

Note that we didn't declare it again. Like any other object, a String object performs services for us. The most important service is to remember the sequence of characters that make it up.

A String can tell us its length.

int val = someWords.length();

A String can also return a new string to us that has all of its own characters together with those of another string.

String more = someWords.concat(" And women's, too. ");

Distinguish carefully between the variable (a name) and the object to which it refers. The name is not an object. It refers to an object.

The String class describes more than 30 services that a String can provide. There is no service, however, to change the characters in a String object. Strings are immutable. However, a String variable can refer to different strings at different times.

class String
{	... // stuff left out
	public int length() 
	{ ... 
	} 
 	public String concat (String s) 
	{ ... 
	} 
	...
} 

In Java, not everything is an Object. Numeric values like 5 aren't objects, since they don't have behavior and can't remember things. They just are. (Like rocks.) All of the complex things that a programmer can define are objects, however. Java also has a large number of classes (like String) that come with the system, so you have lots of possibilities for using objects without building any classes. But usually, you want to build your own kind of objects to do interesting things.

Sometimes errors occur when we ask an object to perform a service. This is considered an "exceptional" situation, and here the server should not be in control. Instead the client should be informed somehow that an exceptional situation has arisen, and the client should then be allowed to react to the situation. It is necessary to manage it this way, since servers serve many clients, and can't know what the client's needs are when services can't be performed. Java provides a special signaling mechanism to do this.

For example, when we ask the doctor for service and the necessary equipment is broken that day, the patient gets to decide whether to wait, or visit another doctor, or go to the emergency room or, ...

THE END.