04 Prepare : Reading
Outcomes
At the end of this week, successful students will be able to:
Show fluency in discussing object composition.
Write programs that correctly use object composition to solve problems.
This week we will dig deeper into our understanding of using class methods, and will also introduce the concept of objects that contain other objects, which is called Composition.
More with methods
As mentioned, we will begin using more objects and methods in more complicated and involved ways. To prepare for this, from Chapter 17, please read the following sections
17.6. Adding Other Methods to our Class (Review this one from last week)
17.7. Objects as Arguments and Parameters
17.8. Converting an Object to a String
17.9. Instances as Return Values
Object composition
In additional to the reading from the online textbook, the following will introduce you to the idea of object composition.
Objects that contain more complicated data
Consider a class for a person, it might contain their first and last name, and other information:
Person |
---|
first_name : string |
last_name : string |
... : ... |
__init__() |
Some of the other information about a person could be their home address. At first, we might decide to add street, city, and zip code directly to the person object. However there are some limitations to this. First, this address information may have other properties, methods, and behaviors that wouldn't make sense for a person such as is_PO_box()
. Also, if the user has two addresses, such as a home and billing address, this would require duplicating lots of member variables.
A better approach is to have the address be a class of its own:
Address |
---|
street : string |
city : string |
state : string |
zip_code : string |
__init__() |
Then, we would say that a person has an address. This relationship is know as composition and is often called a has-a relationship.
Using Composition in Python
It is quite natural to use composition in Python. There are no special constructs. Instead, you create variables, just as you normally would, but the type of data stored in that variable is a complex object, rather than a primitive. For example, a default __init__
function for the person class may look as follows:
class Person:
def __init__(self):
self.first_name = ""
self.last_name = ""
self.home_address = Address()
self.billing_address = Address()
Then, when you create a Person
object, you can access the inner objects properties by chaining together "." calls such as:
bob = Person()
bob.first_name = "Robert"
bob.last_name = "Jones"
bob.home_address.street = "123 North Street"
bob.home_address.city = "Rexburg"
...
bob.billing_address.street = "PO Box 123"
Notice that even though the home address and the billing address are both Address
objects, they can and do have very different values. Just as two string variables can have different values, so can two objects of a complex type.
Working with Multiple Files
A common practice is to put separate Python classes in separate files. Then, these classes are available to use in other programs. Python has a special way of handling different files and the directories they are in, organizing them into modules. But as we get started, we'll keep it simple
Assume that you have two files person.py
and address.py
, and that the code in person.py
needs to know about the class defined in address.py
. (Please be aware that it is customary to name the class Address with a capital A, but to name the file address.py with a lowercase a.)
If these two files are in the same directory, at the top of person.py
, to import the Address
class, you include the following line:
from address import Address
Notice the difference in capitalization here. The first address
is lowercase, because we are noting that it is "from the address.py" file that we will get the class (but we don't say ".py" because Python assumes our address file will have a .py extension). The second Address
is capitalized, because it is the name of the class that we are importing from the provided file.
With that import statement in our file, we can use the code, the same as if it were written directly in our file.