Defining Instance Variables and Methods
A class is a blueprint, or factory, used to construct objects; it describes what objects will contain rather than being the objects themselves
The Cookie Cutter Picture and Its Problem
You have already worked with classes that hold variables and methods, which are subroutines. Objects are built from those same ingredients, so it is natural to ask how an object differs from the class it comes from. Early in a course you may use an object only once and notice little difference. Once a program creates many objects from one class, and creates and discards them while it runs, the difference becomes important to understand.
Many beginners picture object-oriented programming as a set of cookie cutters. The class is the cutter, and every object made from it is a full, independent copy of everything the class describes, including the behavior. Under that picture, if a class has an instance method and you create three objects from it, you would expect three separate copies of that method's code sitting in memory, one inside each object. Before reading on, commit to an answer to the question below.
What do you think happens?
If a class has one instance method and you create three objects from that class, how many copies of the method's compiled code does the program hold?
Reveal answer
One compiled definition that the class defines, with each object logically related to it
The compiled code for a method is a single thing that the class defines. It is not literally true that each object stores its own copy of that code. What each object has is a logical relationship to the method: the method belongs to the object, and the object is the thing you call the method on.
The Class as a Blueprint
A class is a blueprint, or factory, used to construct objects. It describes what objects will contain rather than being the objects themselves. A blueprint for a house does not contain a house, and it does not live in a neighborhood. It specifies what the house will have: its rooms, its doors, and where the walls go. Each house built from that blueprint has the same layout, yet each is a separate building that can be painted a different color or furnished differently. A class plays the same role. It is a description of what objects of its kind will look like, and the objects are the separate things that the description produces.
The description inside a class is split into parts. The non-static parts are the ones that matter for building objects, because they specify which variables and methods each object will contain. The static parts do not describe what each object holds. This is the sense in which the non-static portions of a class describe objects: they set out the structure that every object created from the class will have.
Timing is one of the clearest ways to tell a class and its objects apart. The class is a fixed plan that exists before the program does anything interesting. Objects are temporary products: they appear when the program asks for them and disappear when they are no longer needed. The same class can therefore produce many objects over the lifetime of one program, and those objects do not all need to exist at the same moment.
Where Instance Variables Live
When an object is created using a class, that object is called an instance of the class, and you can say the object belongs to the class. The variables that the object contains are called instance variables. The word instance names the object, so an instance variable is simply a variable that lives inside one particular object.
The key fact is where these variables live. Instance variables are part of the object, not part of the class. The class describes which variables an object will have, but the values belong to each individual object. This is why two objects created from the same class can hold different data at the same time. Most people hear that objects belong to classes and picture it the same way a member variable belongs to its class. That picture hides the useful fact: a member variable is part of the class's own definition, while an object is a separate item that the class helps to produce. The word belong suggests ownership of a part, when what really happens is construction of a new item.
The source illustrates the idea with a PlayerData class. Suppose the class is used to create an object. That object is an instance of PlayerData, and its name and age variables are instance variables of that object. The example below uses that class to trace what happens when two objects are created and one of them changes.
Tracing two PlayerData objects
The PlayerData class describes two instance variables, name and age. Create two objects from it, then change the age in one of them. What does the other object hold?
- 1Create the first object
The class is used to construct an instance. This object gets its own name variable and its own age variable. Assign name to Ana and age to 30. Its state is now name Ana, age 30.
- 2Create the second object
A second construction from the same class produces a separate object with its own name and age variables. Assign name to Ben and age to 25. Now two objects exist, each with its own values, and the class itself holds no player data.
- 3Change one object
Set the age of the first object to 31. Only the first object's age variable changes. The second object still holds age 25, because its age variable is a different variable that lives in a different object.
- 4Read both states
The first object is name Ana, age 31. The second object is name Ben, age 25. The class description is unchanged, because the values were never stored in the class.
Two objects built from one class hold separate values. Changing one object's instance variables does not affect the other.
Instance Methods and Logical Membership
The same idea extends to behavior. The subroutines that an object contains are called instance methods. Instance methods are the non-static methods, and they become part of the objects created from the class. The source's examples focus on variables, but methods work similarly. Because an instance method is logically part of the object, you can think of the object as carrying its behavior along with its data. The object contains both its instance variables and its instance methods in the logical sense.
The cookie cutter picture breaks down at this point. The compiled code for an instance method is a single thing that the class defines. Each object does not get its own copy of that code. What each object has is a logical relationship to the method: the method is one of the things that belongs to the object, and the object is the thing you call the method on. When you call the method on one object, the method works with that object's instance variables, and a different object can call the same method and see its own values.
Static Methods Versus Instance Methods
Not every method belongs to objects. The source contrasts two kinds. Static methods are part of the class, and they are associated with the class rather than with objects. Non-static methods, which are the instance methods, become part of the objects created from the class. Keeping this contrast in mind prevents a common confusion about where a method lives. The question to ask is always whether the method is tied to the class as a whole or to an individual object created from it.
Mistakes Beginners Make With Classes and Objects
Common mistake Treating a class as if it were one of the objects it creates
Why it failsA class describes what objects will contain. It is the blueprint, not a house built from it. The objects are the separate things that the description produces.
Do this insteadAsk whether you are talking about the description, which exists before the program does its work, or about an object, which is created and destroyed while the program runs.
Common mistake Expecting each object to store its own copy of an instance method's compiled code
What it looks likeCreating three objects and assuming three copies of the method's code exist in memory.
Why it failsThe compiled code for a method is defined once by the class. Objects have a logical relationship to the method, not a separate stored copy of the code.
Do this insteadThink of the method as belonging to each object logically, while its code remains a single definition in the class.
Common mistake Storing object-specific values in the class rather than in the object
What it looks likeAssuming that changing the age of one PlayerData object also changes the age of every other PlayerData object.
Why it failsInstance variables are part of each object, so each object holds its own values.
Do this insteadTrace each object's instance variables separately, as in the two-object example above.
Common mistake Assuming every method belongs to objects, when static methods are associated with the class instead
Practice Tracing Object State
Using the PlayerData class from this article, create three objects: first with name Cara and age 40, second with name Dev and age 19, third with name Eli and age 33. Then change the age of the second object to 20. List the final name and age of each object, and state whether the class itself holds any player values.
Hints
- Each object gets its own name and age variables, so each one keeps separate values.
- Changing the second object's age should not touch the first or third object.
- Values are stored in the objects, so the class holds only the description of what each object will contain.
Key Takeaways
- A class is a blueprint, or factory, that describes what objects will contain; the objects are separate items created while the program runs.
- The non-static parts of a class specify the instance variables and instance methods that each object created from it will have.
- Instance variables are part of each object, so every object keeps its own values even when the objects come from the same class.
- Instance methods logically belong to each object, but their compiled code is defined once by the class rather than copied into every object.
- Static methods are associated with the class, while non-static (instance) methods become part of the objects created from the class.