int value; //Declare an integer variable named value. value=100; // Store the number 100 in value. System.out.println(value); // Print the number in value, "100" value=20; // Put 20 in value. Over-writes the 100. count=value; // Gets the number from value and puts // it in count. // Assumes 'count' was declared as an int before.
When we use objects, we're using a more complex kind of variable. We don't do it for the sake of complexity, but because adding some complexity here makes things a lot simpler elsewhere in our program. A lot simpler.
Object variables are called "reference types", the type is actually the class that the object belongs to. The difference between a reference variable and a primitive variable is that a primitive variable actually is a storage location in computer memory that holds the stored information. A reference variable is a name that names a specific type of information. It doesn't actually hold the information, it's just associated with an object that actually holds the information.
This why there's a two step process in creating a Java variable. The first step, declaration, sets up a name we're going to use for a particular type of object. The second step, initialization, associates that name with an object--creating a new object if necessary.
Let's say I'm talking to a friend. I say, "I'm going to get a hamster and call it Wilmot."
"That's nice," says the friend. "Can I see Wilmot?"
"I don't have him yet."
"What color is Wilmot?"
"I don't know, I don't have a hamster yet."
Then I go to the pet store and pick up a hamster. I call him Wilmot, put him in a cage and take him home. I've now initialized the name Wilmot I declared to my friend earlier to point to a specific hamster.
Now when my friend says "Can I see Wilmot?" I can show him a hamster, and say "This is Wilmot." When he wants to know the color, there is an object to get the color of.
In Java terms, if I had a Hamster class, I could declare a name like this:
Hamster wilmot;
I now have a name for a Hamster object, but no Hamster. I can initialize the reference variable by getting a new Hamster object using the class's constructor, Hamster():
wilmot=new Hamster();
Now I have a Hamster object associated with the name. The name references the Hamster object that's been created. Hence the term "reference variable".
Now, if I create a new name and make it point to the same Hamster object, it becomes a new name for the same object:
Hamster fluffy; fluffy=wilmot;
Now, if I make any changes to fluffy they also happen to wilmot. For example, if wilmot's size is 10cm, and I set fluffy's size to 12cm, then get wilmot's size it will be 12cm.
This is different from what happens with primitive variables. If I do the same thing with a pair of primitive variables like this:
int value, count; value=100; // Initialize value to 100; count=value; // Set count equal to value. count=count-20; // Subtract 20 from count. // We could have said 'count-=20;', too. System.out.println("value= " + value); // Print value. System.out.println("count= " + count); // Print count.
Then the output will be:
value= 100 count= 80
With a primitive variable, when we set it equal to another primitive we get a copy of the value in that primitive's own storage. When we set a reference variable equal to another reference variable, we are now referring to the same object as the other reference variable. In pet terms, it's like giving our hamster a second name. We might call it wilmot or fluffy, but they're both the same hamster.
If we need to have each name apply to a different hamster, we need to go back to the pet store for another hamster. In Java, we need to use the constructor to get another Hamster object:
Hamster wilmot, fluffy; wilmot=new Hamster(); fluffy=wilmot; // fluffy and wilmot are now both names // for the same Hamster object. Anything we do to fluffy // will also apply to wilmot, and vice versa. fluffy=new Hamster(); // Now fluffy applies to a different Hamster object. // We can make changes to fluffy and // they won't affect wilmot. We now have two // Hamster objects, each with its own name // to refer to it.
But what if we want it to act like a primitive object? What if we want a copy of wilmot to make changes to without affecting wilmot? Then we use a method of the object's class to create a new object that's a copy of that object. Usually this will be clone():
Hamster wilmot, fluffy; wilmot=new Hamster(); fluffy=wilmot.clone();
Now fluffy is a copy of wilmot, and we can make changes to fluffy without affecting wilmot. Note: whether a class has the clone() method varies from class to class. Normally, if the class implements the Clonable interface then it has a clone() method that works this way.
0 comments:
Post a Comment