Inheritance in Python
00:00 In the previous lesson, I give you an overview of the course. In this lesson, I will introduce you to inheritance in Python. Inheritance is a way of structuring code where classes form hierarchies.
00:13 A child class is one based on a parent and gains all the aspects of the parent with the ability to override some of those features. This mechanism is useful for writing objects that reflect hierarchical relationships in the data itself and reducing the amount of code you write, keeping common code in a parent class and having one or more child classes inherit that code.
00:37 Inheritance terminology has a fair number of synonyms. The class you inherit from is sometimes called a parent, like I did in the previous slide, a super class, or a base class, with an abstract base class being a special case of a class that doesn’t fully implement all its methods.
00:55 It’s a placeholder saying my children should have a method that does this. A class that inherits from a parent can be called a child, like I’ve been doing here, a derived class, a subclass (as opposed to a superclass).
01:11 And the process of creating a child is sometimes known as extending the parent class. Why is there so much terminology? Partially because there are a whole whack of programming languages that have object-oriented concepts built in, and each has their own take. The different terms from different languages and academic papers have blended together over the years.
01:42 When a child extends a parent class, it gets all of the parents’ methods. The child class can then do one of three things with the inherited method. First, it can do nothing, meaning when the method is called, the code in the parent gets run. Second, the child class can override the method, making a method of the same name.
02:01 When the child’s version of the method is called, only the child’s version gets run, completely overriding the parent’s functionality. Third is to extend a method. In this case, the child is also writing a method of the same name, but somewhere in the code, it’s invoking the parent’s code.
This can be useful if you want to add to the functionality but not replace it, allowing for code reuse. In Python, you can access the methods in a parent class using a built-in callable named
This callable returns an instance of the current object within the parent’s context. So,
super().method() invokes the parent’s copy of the method, allowing you to write a child version of that method that extends the parent’s functionality. Let’s go look at some code that uses inheritance.
This is the
AirCraft class. It starts out with the keyword declaring it as a class. The special method for initialization called
.__init__() is called after the instance object is instantiated, giving you the opportunity to set initial values on the object.
Remember, all instance methods need the
self argument, a reference to the object you’re interacting with. This code stores the
model arguments on the object and also creates a non-public attribute called
.takeoff() instance method prints out a message and changes the value of the non-public attribute
._flying to be true, and below it, the
.land() method does the opposite. Let me scroll down.
I could just redo the two lines that stores
model on the object, but instead I’m invoking the parent’s
.__init__(). Line 20 does that, using
super() to get at the object in the parent’s context, and then directly calling its copy of
.__init__() passing in the make and model.
Even if you know the parent does nothing but store these two values, it’s good practice to use
super(). That way, if additional code is added to the parent class, you get it automatically without having to worry about what the child’s doing.
By defining a method with the same name,
Plane can modify the parent’s behavior. On line 24, I use
super() to call
.takeoff() method, making sure not to lose its functionality, and then add some more code in the line after with some extra printing.
The make is stored on
Plane because I invoked
super(). And when I call the
.takeoff() method, it also uses
.takeoff(), which prints out the first message, and then the extended code calls the gear up through the use of
06:38 You can control what parts of the parent’s code gets run, and you can also control when. Most of the time when you’re extending a method, you’ll invoke the parent’s version first, but you don’t have to.
Sometimes you might want to change your object’s state before calling the parent. The use of
super() merely accesses the parent context. You can call whatever methods on it in whatever order as you need.
07:03 Inherited classes can also be extended, so you can end up with a whole hierarchy. This is a class object diagram. Each box represents a class and has three sections: the title, the middle section defining attributes, and the bottom section defining methods.
Animal class on the top defines an attribute called
.name and has no methods. The
Fish classes each inherit from
Animal, gaining its
.name attribute, and then they further add their own attribute named
07:38 In this case, each class adds the same attribute, but that isn’t necessary. At first glance of this diagram, you might rightfully think that feature could be moved up into the parent, but you’ll see why it isn’t when I show you the actual code that goes with this.
The bottom layer here defines classes that extend
Fish. Each defines a method for itself. That
"None" denotes the return value of the method. Notice how
Penguin define different methods.
The short version is these are common across all the instance objects that are built from the class. At the third level, you see some classes that inherit from
Fish, each defining its own methods.
Become a Member to join the conversation.