Chapter 10, Lesson 1 Text
Lesson One: Thinking about Objects
So far, your programs have used a simple series of individual statements. Together, those statements produced some useful program behavior. However, none of the code you have written could be easily re-used in other projects! It is possible to write functions that do useful work, but what is the best way to organize, maintain and access those functions?
As early as the 1960's, software engineers began defining a philosophy known as Object-Oriented Programming, or "OOP" for short. OOP uses software objects to organize re-usable code and to represent real-world concepts or things. In this chapter, you are going to begin writing your own Python objects. Let's begin by exploring what makes up a software object.
Defining an Object
OOP revolves around the creation of re-usable code objects. An object is generally defined by three concepts.
|Data||Objects may own one or more data values or properties. These values are stored in variables that belong to the object.|
|Behavior||Objects may act in certain ways. These actions are coded in methods, which are functions that belong to the object.|
|Relationships||Objects may interact with each other. They may also form related families where some objects share or inherit features from other objects.|
Ideally, well-coded objects will be useful to many different applications and can therefore be shared between different programs. The Python core library and other add-on libraries like random and datetime all contain objects that you have re-used in your own code.
Deciding what kind of data, behavior and relationships to code into an object can be an art form where there is no one right answer! If you can identify a concrete thing in real life, then you might choose to define a similar software object to represent that real life concept. For example, if you are writing a racing simulator program, then you might reasonably define a Car object with data and behavior that makes sense for a real-life car. The Car could own data such as a model, color, speed and direction, and it could also provide behavior like accelerate(), break() or turn().
Sometimes, and object is just a collection of functions or methods and the object doesn't store any useful data internally. However, in many cases, objects will need to store data relating to the object. These properties are held in variables that belong to the object.
Think about an object that represents a smart-phone. What kinds of data might a SmartPhone object store to describe itself?
- model_name (string)
- color (string)
- price (float)
- phone_number (string)
- signal_strength (int)
It's possible that some objects might store and use other objects and not just simple data types. A SmartPhonemight also reasonably contain the following objects:
- Camera – an object that takes pictures through a built-in lens
- GPS – an object that calculates the phone's current location using satellite navigation data
Deciding what data should belong to your object and how that data is defined by variables is part of the design decisions that programmers must make when creating new objects.
Objects use functions in order to take some specific action or to produce useful behavior. When a function belongs to an object, it is also called a method. You have used methods belonging to objects already! Recall the Python datetime library has objects like datetime that hold methods such as strftime() and strptime().
An object method works just like a standalone function. It can receive data parameters and return a data value. The method might also have special access to internal object data, as we'll discuss in future lessons. When designing methods for your object, ask yourself "What do I want this object to do for me?"
For example, think about a SmartPhone object again. What kind of actions or behavior does a SmartPhonenormally show? The following methods might reasonably be attached to a SmartPhone:
You can easily imagine what these or similar methods would do for smart-phone. Each method may require specific input parameters. The dial() method, for example, might require a phone number as input. Similarly, each method may produce output data. The take_picture() method could return a picture or the name of the picture stored on the internal file system.
When designing your object methods, one goal might be to make your object as re-usable as possible. Each program might want to use an object in a slightly different way. Therefore, your object methods may need to be flexible and provide a number of options for different programs to accomplish similar tasks.
It is possible for objects to interact with each other in a number of ways. There are three general types of relationships between objects.
|uses-a||One object may use another object by calling methods (functions) on that object. But the objects are not otherwise tied together.|
|has-a||One object may actually "own" another object as part of its internal data.|
|is-a||One object may actually be a more specialized type of another parent object. The more specialized type can inherit some features of the parent object and then add in its own unique features.|
Let's think through some examples of each relationship. A Person object might use a SmartPhone object. But the Person would not necessarily "have-a" SmartPhone in a tight relationship. The SmartPhone exists independently of the Person and might actually be used by more than one Person. So this would best be described as a "uses-a" relationship.
However, a Person does certainly have some major internal pieces that belong strictly to that Person and generally exist so long as the Person object exists. Think about Heart, Lung and Stomach objects. it would be reasonable to say a Person "has-a" Heart, Lung and Stomach object, so this is a "has-a" relationship.
Finally, think about a Superhero object. The Superhero is actually a special type of Person that has some extra data and behavior. Perhaps the Superhero has X-ray eyes and can fly(), in addition to all of the normal things that make up a Person. In that case, it would be correct to say that a Superhero "is-a" Person.
We will be creating objects that have a "uses-a" or "has-a" relationship with other objects. Designing objects that inherit features from others with an "is-a" relationship is a more advanced topic.
In Python, and in most other programming languages, an object is called a class. So, to define an object in Python, we begin with the "class" keyword. Add the name of the object after the class keyword and end the statement with a colon (:). The example below begins the definition of a class called SmartPhone.
class SmartPhone: #statements belonging to the class indented here # other program statements go here
After the class statement, you will add one or more additional lines indented to the right. All of those lines will make up the data (variables) and behavior (methods) that belong to the class. The class definition ends at the first non-indented line.
You must follow the same general naming rules for classes that you do for variables and functions. Use only letters, numbers and underscores, avoid spaces and other special characters and so on.
Class names are case-sensitive just like any other variable or function name. So, smartphone, SmartPhone, and SMARTPHONE are all different class names. While you can select the naming style that you prefer, many programmers will use "Camel Case" as in SmartPhone when naming classes. We will use this pattern ourselves in our own examples.
In the next lesson, we'll start showing you how to add variables and methods to a Python class!
Work with Me: Design Discussion
Select an object that you use every day such as a phone, television, computer, refrigerator, or bike. Or, select an item from your favorite hobby. How would you write the object's name in a Python class?
Next, practice defining this object's data, methods and relationships.
Think about the properties of your object. What data values would you likely store in this object in order to describe or represent it? Try to come up with at least 3 descriptive values for your object.
What does your object do? What actions can you take with the object or what commands can you issue to the object? What kinds of tasks might the object perform on its own? Try to define at least three methods (functions) that would belong with the object. Describe any input values and output data the functions would require and return.
Does your object interact with any other objects? Try to think of at least one other object that would be in a "uses-a" relationship with yours. Your object could use another object, or another object might use yours.
Next, think of an object that might be in a "has-a" relationship with your object. Your object might be complex and reasonably include a number of smaller objects as internal data. Or, your object might itself naturally belong to a larger or more complex object.
Be prepared to describe your object and justify your data, method and relationship decisions in a discussion with your class or teacher.