Chapter 4

Object-Oriented Python

Model data and behavior with classes and objects.

Creating a class

A class is a blueprint for objects. It describes the shape of related data and behavior before any particular object exists.

This is useful when several things in your program share the same kind of information. Instead of treating each one as a special case, you define the common structure once and create as many objects as you need.

EXAMPLE
Output will appear here.

Pause after running the example and explain each line in your own words. Notice what the program reads, what it stores, and what it prints, then make one small change and run it again to see exactly what changed.

Practice

Work through the same idea a few times so it starts to feel familiar. Begin by copying the example, then make the single change the instruction asks for, and finally explain to yourself why the result changed.

Type `class Cat:` followed by `pass`, then make `pet = Cat()`.
EXERCISE
Output will appear here.
Rename `Cat` to `Dog` everywhere.
EXERCISE
Output will appear here.
Predict what `type(pet)` describes.
EXERCISE
Output will appear here.
Create a `Book` class with `pass`, then make one object.
EXERCISE
Output will appear here.

Constructors

__init__ sets up the data each new object needs. It runs as the object is being created, which makes it the right place to give the object its first values.

If you imagine a class as a blueprint, then the constructor is the part that fills in the starting details for each new instance.

EXAMPLE
Output will appear here.

Pause after running the example and explain each line in your own words. Notice what the program reads, what it stores, and what it prints, then make one small change and run it again to see exactly what changed.

Practice

Work through the same idea a few times so it starts to feel familiar. Begin by copying the example, then make the single change the instruction asks for, and finally explain to yourself why the result changed.

Write a `Dog` class whose `__init__` stores `self.name`.
EXERCISE
Output will appear here.
Create a dog named `Mochi`, then change the name passed in.
EXERCISE
Output will appear here.
Predict what `pet.name` prints for `Dog("Ada")`.
EXERCISE
Output will appear here.
Create a `Book` class that stores a title and print the title.
EXERCISE
Output will appear here.

Methods

Methods are functions attached to an object. They let the object act on its own data instead of forcing the rest of the program to reach in and manage every detail manually.

This is one of the reasons object-oriented code can stay tidy: the behavior sits next to the data it belongs to.

EXAMPLE
Output will appear here.

Pause after running the example and explain each line in your own words. Notice what the program reads, what it stores, and what it prints, then make one small change and run it again to see exactly what changed.

Practice

Work through the same idea a few times so it starts to feel familiar. Begin by copying the example, then make the single change the instruction asks for, and finally explain to yourself why the result changed.

Add a `speak` method that returns a sentence using `self.name`.
EXERCISE
Output will appear here.
Change the returned sound from `woof` to `meow`.
EXERCISE
Output will appear here.
Predict what changes when the name is `Rin`.
EXERCISE
Output will appear here.
Create a `describe` method that returns an object’s name.
EXERCISE
Output will appear here.

Changing state

Methods can update attributes on self. This means the object can remember what happened last time and behave differently the next time you call one of its methods.

Each Counter object has its own value. Calling increment changes the value stored on the particular object named counter; it does not change every possible counter.

When you work with state, always ask whether you are changing one object, returning a new value, or both. That distinction matters a lot once objects start doing real work.

EXAMPLE
Output will appear here.
An object remembers its own stateChange this one object without changing the class blueprint.
  1. pet.name is Mochi
  2. pet.walks is 0
  3. Calling a method can update only this object’s stored values.

Pause after running the example and explain each line in your own words. Notice what the program reads, what it stores, and what it prints, then make one small change and run it again to see exactly what changed.

Practice

Work through the same idea a few times so it starts to feel familiar. Begin by copying the example, then make the single change the instruction asks for, and finally explain to yourself why the result changed.

Write a `Counter` with `value = 0` and an `increment` method.
EXERCISE
Output will appear here.
Call `increment()` twice instead of once.
EXERCISE
Output will appear here.
Predict the value after three calls.
EXERCISE
Output will appear here.
Make a `Score` object with an `add_point` method.
EXERCISE
Output will appear here.

Inheritance

A child class can reuse behavior from a parent class. This lets related objects share common behavior while still changing the parts that are different.

Inheritance is most helpful when the child really is a more specific version of the parent. If the relationship feels forced, it is usually better to keep the classes separate.

EXAMPLE
Output will appear here.

Pause after running the example and explain each line in your own words. Notice what the program reads, what it stores, and what it prints, then make one small change and run it again to see exactly what changed.

Practice

Work through the same idea a few times so it starts to feel familiar. Begin by copying the example, then make the single change the instruction asks for, and finally explain to yourself why the result changed.

Write `class Bird(Animal):` and give it its own `move` method.
EXERCISE
Output will appear here.
Change the returned movement word.
EXERCISE
Output will appear here.
Predict which `move` method `Bird().move()` uses.
EXERCISE
Output will appear here.
Make a `Car` parent and an `ElectricCar` child with a different `fuel` method.
EXERCISE
Output will appear here.

Useful representations

__repr__ gives objects a helpful developer-facing description. When you print an object or inspect it in a debugger, this method helps you see the important parts without digging into the object manually.

A good representation is short, specific, and easy to read while you are debugging.

EXAMPLE
Output will appear here.

Pause after running the example and explain each line in your own words. Notice what the program reads, what it stores, and what it prints, then make one small change and run it again to see exactly what changed.

Practice

Work through the same idea a few times so it starts to feel familiar. Begin by copying the example, then make the single change the instruction asks for, and finally explain to yourself why the result changed.

Write `__repr__` for a `Book` that includes its title.
EXERCISE
Output will appear here.
Create a book with a different title.
EXERCISE
Output will appear here.
Predict what `print(Book("Rain"))` shows.
EXERCISE
Output will appear here.
Make a `Point` class whose representation shows `x` and `y`.
EXERCISE
Output will appear here.