Bundling information into objects (Part 1)
Bundling items
We've used sequences as ways of joining together values of the same type, typically where each value plays a similar role. What about joining together values that play different roles in a computation?
In real-life settings, we bundle together related items in a box. We might collect related but differing tools in a box, with a compartment for each item. There are always food-related examples to be found like the assorted chocolates shown in the figure.
- Different kinds of boxes exist.
- Boxes have slots for different items.
We observe that there are different kinds of boxes such as tool boxes and chocolate boxes, and that there are specialized slots for different items.
Grouping related data
We can think of a box-like way of joining related data. A date might consist of the month name as a string and two integers for the day and year, example "October" 10 1896. A point might be defined by its x and y coordinates, for example 8 53. For latitude and longitude, perhaps four values would be stored, for example 43.4667° N, 80.5167° W. For an address, perhaps three, for example "University of Waterloo" "200 University Ave. West" "N2L 3G1" Here's some useful terminology to talk about bundles.
Definition
A class is a type of bundle, such as the class of all points.
An object is an actual bundle, such as the point 8 53.
An attribute is a slot for an item, such as an x-coordinate.
Each type of bundle is called a class. Here we've talked about four different classes. An example of a bundle, with particular values, is called an object. We use the term attribute to refer to one of the slots for an item in a bundle.
Deconstructing dinner
Let's illustrate the terms using TV dinners as an example of a class. Here, the TV dinner comes with a choice of beef or turkey, each with its own choice of vegetables, side, starch, and main dish.
Class: dinner
Objects: beef, turkey
Attributes: vegetables, side, starch, main dish
Objects are specific choices of foods to put in the slots, here a beef dinner and a turkey dinner. Each has four slots for the following attributes: vegetables, a side, a starch, and a main dish.
Visualizing objects
Consider another example of an object called lunch, which is of the class “Time”. Assume that the class “Time” has attributes hour, min, and sec. Suppose that the object lunch has attribute values hour = 12, min = 0, and sec = 0.Class: Time
Objects: lunch
Attributes: hour, min, sec
Values: 12, 0, 0
We can view an object being stored in memory as a bundle of addresses, where the name of the object is stored with the address of the bundle. Just like indices are used to label addresses in sequences, here names of attributes are used to label the addresses in the bundle. The values associated with the attribute addresses are the values of the attributes.
A class as a factory
Another way to view a class is a factory that makes items of a particular variety. There can be individual differences, like in the case of the TV dinners, but only within the limitations of the attributes.
Designing a class
The design principles for a class echo many of the design principles we've been using all along.
Class design recipe
- Choose meaningful attribute names.
- Choose attribute types.
- Record attribute names and types of attributes.
We choose names that convey meaning, and types that fit our needs. Moreover, we ensure that this information is documented, for example, in comments.
Pseudocode for objects
Using as an example the “Time” class seen earlier, we use an assignment statement in which we provide the values for the attributes in order. We use dot notation to refer to a particular attribute of an object, where we use the name of the attribute. lunch ← Time(12, 0, 0)} print(lunch.hour)
For some languages, there may be automatically created functions associated with a class. Such common functions include functions that
- create objects,
- determine if an object is in a particular class, or
- determine if objects are equal.
Bundles inside bundles
There is no restriction on what type of value can be stored in an object.
The figure shows an “Event” object that consists of two “Time” objects and a string. More specifically, the “Event” object called swim contains two “Time” objects called start and end and a string called name. As before, “Time” objects have attributes hour, min, and sec. In this example, the stored values associated with attributes of the object start are hour = 7, min = 30, and sec = 0. The stored values associated with attributes of the object end are hour = 8, min = 0, and sec = 0.
The dot notation swim.start refers to an “Time” object for which we can use swim.start.min to extract the attribute for minutes, with value 30.
Mutation
Since objects are mutable, we can list an attribute on the left side of an assignment statement, resulting in a change to the object.
For example, consider the object shown in figure 1. Here we have a “Time” object called lunch with attribute values hour = 12, min = 0, and sec = 0. Since objects are mutable, the pseudocode lunch.sec ← 15 changes the value of the attribute sec from 0 to 15, as shown in figure 2.
Aliasing
Consequently, we need to be concerned with aliasing, where an object can be accessed by two different names, and a change under one name changes the value stored under both.
For exampe, consider again the object shown in figure 1, where we have a “Time” object called lunch with attribute values hour = 12, min = 0, and sec = 0. Then the pseudocode noon ← lunch noon.sec ← 15 creates another name, noon, for the “Time” object, as shown in figure 3, and setting noon.sec ← 15 changes the attribute of sec from 0 to 15 in both lunch and noon, as shown in figure 4.
Methods
Definition
A method is a function associated with a class.
A class contains not only bundles of values, but also functions that can act on those bundles. These use dot notation with the first parameter of the function being followed by a dot and the function name, just as we used for strings. This is no coincidence as in many languages strings are objects.
Advantages of using methods
Why use methods instead of functions?
- Methods can only be used on the right type of data:
One advantage is that methods can only be used on data of the correct type, keeping us from making errors. - Related functions are grouped together:
Associating functions with classes also ensures that related functions are grouped together in a logical way