> ### Section 5.1
> Objects, Instance Methods, and Instance Variables

> OBJECT-ORIENTED PROGRAMMING (OOP) represents an attempt to make programs more closely model the way people think about and deal with the world. In the older styles of programming, a programmer who is faced with some problem must identify a computing task that needs to be performed in order to solve the problem. Programming then consists of finding a sequence of instructions that will accomplish that task. But at the heart of object-oriented programming, instead of tasks we find objects -- entities that have behaviors, that hold information, and that can interact with one another. Programming consists of designing a set of objects that somehow model the problem at hand. Software objects in the program can represent real or abstract entities in the problem domain. This is supposed to make the design of the program more natural and hence easier to get right and easier to understand.

> To some extent, OOP is just a change in point of view. We can think of an object in standard programming terms as nothing more than a set of variables together with some subroutines for manipulating those variables. In fact, it is possible to use object-oriented techniques in any programming language. However, there is a big difference between a language that makes OOP possible and one that actively supports it. An object-oriented programming language such as Java includes a number of features that make it very different from a standard language. In order to make effective use of those features, you have to "orient" your thinking correctly.

> Objects are closely related to classes. We have already been working with classes for several chapters, and we have seen that a class can contain variables and subroutines. If an object is also a collection of variables and subroutines, how do they differ from classes? And why does it require a different type of thinking to understand and use them effectively? In the one section where we worked with objects rather than classes, Section 3.7, it didn't seem to make much difference: We just left the word "`static`" out of the subroutine definitions!

> I have said that classes "describe" objects, or more exactly that the non-static portions of classes describe objects. But it's probably not very clear what this means. The more usual terminology is to say that objects belong to classes, but this might not be much clearer. (There is a real shortage of English words to properly distinguish all the concepts involved. An object certainly doesn't "belong" to a class in the same way that a member variable "belongs" to a class.) From the point of view of programming, it is more exact to say that classes are used to create objects. A class is a kind of factory for constructing objects. The non-static parts of the class specify, or describe, what variables and subroutines the objects will contain. This is part of the explanation of how objects differ from classes: Objects are created and destroyed as the program runs, and there can be many objects with the same structure, if they are created using the same class.

> Consider a simple class whose job is to group together a few static member variables. For example, the following class could be used to store information about the person who is using the program:

>             class UserData {
>                 static String name;
>                 static int age;
>             }

> In a program that uses this class, there is only one copy of each variable in the class, `UserData.name` and `UserData.age`. The class, `UserData`, and the variables it contains exist as long as the program runs. Now, consider a similar class that includes non-static variables:

>             class PlayerData {
>                String name;
>                int age;
>             }

> In this case, there is no such variable as `PlayerData.name` or `PlayerData.age`, since `name` and `age` are not static members of `PlayerData`. So, there is nothing much in the class at all -- except the potential to create objects. But, it's a lot of potential, since it can be used to create any number of objects! Each of those objects will have its own variables called `name` and `age`. A program might use this class to store information about multiple players in a game. Each player has a name and an age. When a player joins the game, a new `PlayerData` object can be created to represent that player. If a player leaves the game, the `PlayerData` object that represents that player can be destroyed. A system of objects in the program is being used to dynamically model what is happening in the game. You can't do this with "static" variables!

> In Section 3.7, we worked with applets, which are objects. The reason they didn't seem to be any different from classes is because we were only working with one applet in each class that we looked at. But one class can be used to make many applets. Think of an applet that scrolls a message across a Web page. There could be several such applets on the same page, all created from the same class. If the scrolling message in the applet is stored in a non-static variable, then each applet will have its own variable, and each applet can show a different message. The situation is even clearer if you think about windows, which, like applets, are objects. As a program runs, many windows might be opened and closed, but all those windows can belong to the same class. Here again, we have a dynamic situation where multiple objects are created and destroyed as a program runs.

> An object that belongs to a class is said to be an instance of that class. The variables that the object contains are called instance variables. The subroutines that the object contains are called instance methods. (Recall that in the context of object-oriented programming, "method" is a synonym for "subroutine". From now on, for subroutines in objects, I will prefer the term "method.") For example, if the `PlayerData` class, as defined above, is used to create an object, then that object is an instance of the `PlayerData` class, and `name` and `age` are instance variables in the object. It is important to remember that the class of an object determines the types of the instance variables; however, the actual data is contained inside the individual objects, not the class. Thus, each object has its own set of data.

> An applet that scrolls a message across a Web page might include a subroutine named `scroll()`. Since the applet is an object, this subroutine is an instance method of the applet. The source code for the method is in the class that is used to create the applet. Still, it's better to think of the instance method as belonging to the object, not to the class. The non-static subroutines in the class merely specify what instance methods objects created from the class will contain. The `scroll()` methods in two different applets do the same thing in the sense that they both scroll messages across the screen. But there is a real difference between the two `scroll()` methods. The messages that they scroll can be different. (You might say that the subroutine definition in the class specifies what type of behavior the objects will have, but the specific behavior can vary from object to object, depending on the values of their instance variables.)

> As you can see, the static and the non-static portions of a class are very different things and serve very different purposes. Many classes contain only static members, or only non-static. However, it is possible to mix static and non-static members in a single class, and we'll see a few examples later in this chapter where it is reasonable to do so. By the way, static member variables and static member subroutines in a class are sometimes called class variables and class methods, since they belong to the class itself, rather than to instances of that class. This terminology is most useful when the class contains both static and non-static members.

> So far, I've been talking mostly in generalities, and I haven't given you much idea what you have to put in a program if you want to work with objects. Let's look at a specific example to see how it works. Consider this extremely simplified version of a `Student` class, which could be used to store information about students taking a course:

>             class Student {

>                String name;  // Student's name.
>                double test1, test2, test3;   // Grades on three tests.

>                double getAverage() {  // compute average test grade
>                   return (test1 + test2 + test3) / 3;
>                }

>             }  // end of class Student

> None of the members of this class are declared to be `static`, so the class exists only for creating objects. This class definition says that any object that is an instance of the `Student` class will include instance variables named `name`, `test1`, `test2`, and `test3`, and it will include an instance method named `getAverage()`. The names and tests in different objects will generally have different values. When called for a particular student, the method `getAverage()` will compute an average using that student's test grades. Different students can have different averages. (Again, this is what it means to say that an instance method belongs to an individual object, not to the class.)

> In Java, a class is a type, similar to the built-in types such as `int` and `boolean`. So, a class name can be used to specify the type of a variable in a declaration statement, the type of a formal parameter, or the return type of a function. For example, a program could define a variable named `std` of type `Student` with the statement

> `Student std;`

> However, declaring a variable does not create an object! This is an important point, which is related to this Very Important Fact:

> In Java, no variable can ever hold an object.
> A variable can only hold a reference to an object.

> You should think of objects as floating around independently in the computer's memory. In fact, there is a portion of memory called the heap where objects live. Instead of holding an object itself, a variable holds the information necessary to find the object in memory. This information is called a reference or pointer to the object. In effect, a reference to an object is the address of the memory location where the object is stored. When you use a variable of class type, the computer uses the reference in the variable to find the actual object.

> Objects are actually created by an operator called `new`, which creates an object and returns a reference to that object. For example, assuming that `std` is a variable of type `Student`, declared as above, the assignment statement

> `std = new Student();`

> would create a new object which is an instance of the class `Student`, and it would store a reference to that object in the variable `std`. The value of the variable is a reference to the object, not the object itself. It is not quite true, then, to say that the object is the "value of the variable `std`" (though sometimes it is hard to avoid using this terminology). It is certainly not at all true to say that the object is "stored in the variable `std`." The proper terminology is that "the variable `std` refers to the object," and I will try to stick to that terminology as much as possible.

> So, suppose that the variable `std` refers to an object belonging to the class `Student`. That object has instance variables `name`, `test1`, `test2`, and `test3`. These instance variables can be referred to as `std.name`, `std.test1`, `std.test2`, and `std.test3`. For example, a program might include the lines

>                 System.out.println("Hello, "  +  std.name
>                                      + ".  Your test grades are:");
>                 System.out.println(std.test1);
>                 System.out.println(std.test2);
>                 System.out.println(std.test3);

> This would output the name and test grades from the object to which `std` refers. Similarly, `std` can be used to call the `getAverage()` instance method in the object by saying `std.getAverage()`. To print out the student's average, you could say:

>                 System.out.println( "Your average is " + std.getAverage() );

> More generally, you could use `std.name` any place where a variable of type `String` is legal. You can use it in expressions. You can assign a value to it. You can even use it to call subroutines from the `String` class. For example, `std.name.length()` is the number of characters in the student's name.

> It is possible for a variable like `std`, whose type is given by a class, to refer to no object at all. We say in this case that `std` holds a null reference. The null reference can be written in Java as "`null`". You could assign a null reference to the variable `std` by saying

> `std = null;`

> and you could test whether the value of `std` is null by testing

> `if (std == null) . . .`

> If the value of a variable is `null`, then it is, of course, illegal to refer to instance variables or instance methods through that variable -- since there is no object, and hence no instance variables to refer to. For example, if the value of the variable `std` is `null`, then it would be illegal to refer to `std.test1`. If your program attempts to use a null reference illegally like this, the result is an error called a null pointer exception.

> Let's look at a sequence of statements that work with objects:

>           Student std, std1,       // Declare four variables of
>                     std2, std3;    //   type Student.
>           std = new Student();     // Create a new object belonging
>                                    //   to the class Student, and
>                                    //   store a reference to that
>                                    //   object in the variable std.
>           std1 = new Student();    // Create a second Student object
>                                    //   and store a reference to
>                                    //   it in the variable std1.
>           std2 = std1;             // Copy the reference value in std1
>                                    //   into the variable std2.
>           std3 = null;             // Store a null reference in the
>                                    //   variable std3.

>           std.name = "John Smith";  // Set values of some instance variables.
>           std1.name = "Mary Jones";

>                // (Other instance variables have default
>                //    initial values of zero.)

> After the computer executes these statements, the situation in the computer's memory looks like this:

> This picture shows variables as little boxes, labeled with the names of the variables. Objects are shown as boxes with round corners. When a variable contains a reference to an object, the value of that variable is shown as an arrow pointing to the object. The variable `std3`, with a value of `null`, doesn't point anywhere. The arrows from `std1` and `std2` both point to the same object. This illustrates a Very Important Point:

> When one object variable is assigned
> to another, only a reference is copied.
> The object referred to is not copied.

> When the assignment "`std2 = std1`;" was executed, no new object was created. Instead, `std2` is set to refer to the same object that `std1` refers to. This has some consequences that might be surprising. For example, `std1.name` and `std2.name` refer to exactly the same variable, namely the instance variable in the object that both `std1` and `std2` refer to. After the string `"Mary Jones"` is assigned to the variable `std1.name`, it is also be true that the value of `std2.name` is `"Mary Jones"`. There is a potential for a lot of confusion here, but you can help protect yourself from it if you keep telling yourself, "The object is not in the variable. The variable just holds a pointer to the object."

> You can test objects for equality and inequality using the operators == and !=, but here again, the semantics are different from what you are used to. When you make a test "`if (std1 == std2)`", you are testing whether the values stored in `std1` and `std2` are the same. But the values are references to objects, not objects. So, you are testing whether `std1` and `std2` refer to the same object, that is, whether they point to the same location in memory. This is fine, if its what you want to do. But sometimes, what you want to check is whether the instance variables in the objects have the same values. To do that, you would need to ask whether "`std1.test1 == std2.test1 && std1.test2 == std2.test2 && std1.test3 == std3.test1 && std1.name.equals(std2.name)`"

> I've remarked previously that `Strings` are objects, and I've shown the strings `"Mary Jones"` and `"John Smith"` as objects in the above illustration. A variable of type `String` can only hold a reference to a string, not the string itself. It could also hold the value `null`, meaning that it does not refer to any string at all. This explains why using the `==` operator to test strings for equality is not a good idea. Suppose that `greeting` is a variable of type `String`, and that the string it refers to is `"Hello"`. Then would the test `greeting == "Hello"` be true? Well, maybe, maybe not. The variable `greeting` and the `String` literal `"Hello"` each refer to a string that contains the characters H-e-l-l-o. But the strings could still be different objects, that just happen to contain the same characters. The function `greeting.equals("Hello")` tests whether `greeting` and `"Hello"` contain the same characters, which is almost certainly the question you want to ask. The expression `greeting == "Hello"` tests whether `greeting` and `"Hello"` contain the same characters stored in the same memory location.

> The fact that variables hold references to objects, not objects themselves, has a couple of other consequences that you should be aware of. They follow logically, if you just keep in mind the basic fact that the object is not stored in the variable. The object is somewhere else; the variable points to it.

> Suppose that a variable that refers to an object is declared to be `final`. This means that the value stored in the variable can never be changed, once the variable has been initialized. The value stored in the variable is a reference to the object. So the variable will continue to refer to the same object as long as the variable exists. However, this does not prevent the data in the object from changing. The variable is `final`, not the object. It's perfectly legal to say

>              final Student stu = new Student();
>              stu.name = "John Doe";  // Change data in the object;
>                                      // The value stored in stu is not changed.

> Next, suppose that `obj` is a variable that refers to an object. Let's consider at what happens when `obj` is passed as an actual parameter to a subroutine. The value of `obj` is assigned to a formal parameter in the subroutine, and the subroutine is executed. The subroutine has no power to change the value stored in the variable, `obj`. It only has a copy of that value. However, that value is a reference to an object. Since the subroutine has a reference to the object, it can change the data stored in the object. After the subroutine ends, `obj` still points to the same object, but the data stored in the object might have changed. Suppose `x` is a variable of type `int` and `stu` is a variable of type `Student`. Compare:

>          void dontChange(int z) {              void change(Student s) {
>              z = 42;                                s.name = "Fred";
>          }                                     }

>          The lines:                            The lines:

>             x = 17;                               stu.name = "Jane";
>             dontChange(x);                        change(stu);
>             System.out.println(x);                System.out.println(stu.name);

>          output the value 17.                  output the value "Fred".

>          The value of x is not                 The value of stu is not
>          changed by the subroutine,            changed, but stu.name is.
>          which is equivalent to                This is equivalent to

>             z = x;                                s = stu;
>             z = 42;                               s.name = "Fred";

[ Next Section | Previous Chapter | Chapter Index | Main Index ]