An Object-Oriented Bedtime Story

Joseph Bergin
Pace University
jbergin@pace.edu
http://csis.pace.edu/~bergin


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

Objects are electronic things. 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.

Metaphor is important since it helps you with a framework for thinking about something unfamiliar. Every metaphor breaks down at some point, however. I will try to point out where the "objects are like people" metaphor breaks down as we go along.

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

Most objects, though they can be active, are pretty passive. They are only active when they are asked to do some specific thing. (I guess objects are like 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 system is a program or a set of programs that work together to do some task for you.)

A program has two parts. First, it is a description of objects and the behavior that is allowed for each kind of object. Second, it is 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. A method is that part of a class that describes some service that the objects of that class can perform.

class Doctor
{	...
	public void fixPain(BodyPart part)
	{	...
	}
}

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

Sometimes there will be only one object of a given class in a program (a singleton) 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. We can also have anonymous objects. These don't have any names. Sometimes they can be referred to indirectly and sometimes not at all. An example of the latter is the situation in which we create an object to carry out a single task and then we discard it immediately.

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, in the human world we can send a message to a person: "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. The person to whom the name refers is the server. Be careful here to distinguish between the name and the person to whom the name refers. The name isn't a server, the person is.

We could use the alias "Doctor" for "Doctor Jane Smith", or we could use the same "Doctor" to refer to another doctor. The context would need to be clear here, of course.

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.

Here is an example. When I ask a class of students to do an assignment, all get exactly the same message. When I do this, I become a homework client and each student becomes a homework server. My expectation is that each server (student) will do something different to carry out the service request. I know from experience that there are several kinds or classes of students. Some are "very conscientious and dedicated" students and some are "very lazy" students. Students of different types can be expected to behave differently. However, even two different students of the same type might behave differently depending on their current state. One might have a lot of free time currently, and the other might have several other assignments due within the next three days. I can expect these students will also behave differently.

Objects that perform the same service also do it differently depending on their type and upon their state. The state of an object is based on what it currently remembers. Since it uses variables to remember much of its state, the state can vary as the program proceeds.

Just as in the medical world, objects live in a world of specialization. A class can be defined to specialize another class.

class Surgeon extends Doctor
{	...
}

class MedicalDoctor extends Doctor
{	...
}

When we extend a class we can redefine how the objects of the new class carry out services defined in the class that is being extended. We can also add new services.

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 in Java, 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. That is to say, the above fragment of code appears within some method of some object. That object is the client here.

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.)

Note that this is where the objects as people metaphor breaks down. In the real world, when you ask a doctor for a service, the doctor immediately asks you for information. This is because such links in the human world are "two way links." In the object world, however, this doesn't happen automatically. When the doctor wants to ask the patient for information, the doctor becomes a client (information client) and the patient becomes a server. Frequent role changing is common in both the real world and the object world. To make this work requires that the doctor object have a reference to the patient object. This has to be specifically arranged in the object world. One way to do so is to have the original client pass a reference to itself to the server in some message. This reference can then be used to send a message back to the original client.

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 creating 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 "Jane Smith" doesn't have a name, but it could be given a name with":

	String doctorName = "Jane Smith"; 

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.


Last Updated: September 22, 2000