Introduction to Programming Week 10
This week we worked primarily on one large project: writing a program to play Pass the Pigs. See the transcript for details, this page will only focus on the concepts introduced.
Part 1: Pass The Pigs
See Pass the Pigs.
Part 2: Finding The Classes
Often, when writing a large program, the most difficult and important part is deciding how to design the program - which classes you need, and how they'll interact.
One way to come up with ideas for the classes you'll need is to make a list of all the important nouns related to the problem or program you want to write. Then you can go through and decide if each noun should be an object of an existing class, an extension of an existing class (see below), in its own new class, or an attribute of some other object.
Part 3: Inheritance
In a game of Pass The Pigs the pigs are very similar, but not identical to, dice. We've already written a Die class, so it would seem like a good idea to use it as a starting point when making a new Pig class.
This type of scenario is actually very common, many classes are simply extensions of previous classes. In object-oriented programming new classes extending existing ones is called inheritance. The "parent" class is called the superclass, and the "child" class is called a subclass.
In Python, we can create subclasses by putting the superclass we want to extend in parentheses at the end of the class definition:
Python actually allows you to list multiple superclasses in a comma-separated list, but this is rarely necessary.
Note that an instance of a subclass is also considered an instance of the superclass, but an instance of the superclass isn't automatically an instance of the subclass. For example, suppose we have a Mammal superclass and a Dog subclass. Then Python would consider every Dog to also be a Mammal, but not every Mammal to necessarily be a Dog.
Part 4: Building The Pig
An instance of a subclass has access to all the methods of the superclass, so you don't have to rewrite them all. However, when writing a subclass you'll often want to redefine some methods to support the the new, subclass specific behavior. If you write a new method in the subclass with the same name as a method in the superclass the new method will override the original one.
If all the new method does is extend the functionality of the original one, it's common to call the original method from within the new one, so the duplicated parts don't have to be rewritten. This is especially common in the constructor, which is almost always overridden:
def __init__(self, otherParameters): """Constructor for Subclass""" ...subclass specific things... Superclass.__init__(self, otherParameters)
Private variables (variables that start with two underscores) in a superclass are also hidden from subclasses.