00:00 As you can probably imagine, large software projects can have tens or even hundreds of classes. What’s interesting is that these classes are often related in some way.

00:13 For example, one class might be very similar to a different class, but with a few small modifications. But what’s wrong with having lots of classes? Clearly, we have the ability to just copy and paste code, so if we need to create a new class that’s similar to an existing one, we can just copy and paste it, right? While that is unavoidable at times, it produces a lot of code—code that is fundamentally unlinked.

00:42 That means that if we need to modify something in one class, we’ll have to make sure to modify it in all of the others, and we might miss one or make the wrong modification somewhere.

00:54 Inheritance helps us to avoid this problem. Inheritance models what is called an is a relationship. To help understand this, let’s think about some real-world examples of is a relationships. For example, a cat is an animal. I don’t think anyone would argue with that.

01:17 Additionally, an apple is a fruit. In other words, we can classify an apple as a fruit. I’m sure you can think of plenty more examples of is a relationships in the real world. Interestingly enough, we can classify something in multiple ways. For example, fish is a food, but it’s also an animal. I am a student, but also a video tutorial author.

01:47 This is the idea behind multiple inheritance, which you will learn about later on. Now, we can ask ourselves, “Does this is a relationship work the other way?” Not necessarily.

02:00 For example, all cats are animals, but not all animals are cats. Dogs are an animal that would not be classified as a cat.

02:10 So, if a cat inherits from an animal, then we can think of the cat description as a more specialized description of an animal. The cat inherits all of the features and behaviors of the more general animal, like needing a source of food to stay alive.

02:29 It can also change some of these features and behaviors. For example, a cat can walk and meow, and it may be furry. We can’t say this about all animals, but we can say this about cats. To solidify this idea in terms of actual Python code, let’s take a look at some classes that utilize inheritance.

02:52 Pretend that we are writing a program to keep track of restaurant employees. To start off, I’ve created this class called Employee. For its instance attributes, it has a name, an age, an ID, and a wage. For its methods, it can clock in, work, clock out, and report required information to its manager.

03:18 Makes sense so far. Let’s add another class to the mix. Here’s a Waitress. We are going to say the Waitress inherits from Employee.

03:28 That means that Employee is the base class, or the parent class, and Waitress is the derived class, or the child class.

03:37 You may also hear these called superclass and subclass. This inheritance means that even though you don’t see it in the diagram for the Waitress, the Waitress now has its own name, age, ID, and wage, and it’s got the same methods as the Employee.

03:57 It’s also adding its own attributes and methods. A Waitress object keeps track of its number of shifts and the grand total of its earned tips from that day. It can also take a break and work.

04:12 This would mean that in its current state, the Employee has four attributes and the Waitress has six. But take a look at the number of methods in each class.

04:24 The Employee has four methods, but how many methods does the Waitress have?

04:30 You might think six, but here the answer is actually five. That’s because while the Waitress does have a new method called .take_break(), it overrides the .work() method from its parent. In the real world, that would mean that a waitress works differently than a more general employee.

04:52 Both classes declare a .work() method, but their implementation—which is the code that makes up the method—is different. Ask yourself, “Does this inheritance model an is a relationship?” Yes, because every Waitress is also an Employee.

05:11 A Waitress is a specialized version of Employee. Finally, to finish off our program, we can create a separate Cashier class that also inherits from Employee.

05:25 This class only adds one new attribute and it doesn’t declare any new methods. It just overrides the .work() method from its parent class, just like the Waitress class does. This class also passes the relationship test.

05:41 A Cashier is an Employee.

05:45 Inheritance can be pretty confusing at first, so I’ve created a few questions that will help you to test your understanding of the subject. Pause this video and see if you can answer them for yourself.

06:00 All right, first question. Does a Waitress object have the ability to clock in? The answer is yes.

06:09 The Waitress inherits all of the attributes and methods from the Employee, including the .clock_in() method. This means that you can call that method on a Waitress object and it will clock in the same way a more generic Employee object would. Next, does an Employee have a .shifts attribute? Here, the answer is no, because .shifts is specific to Waitress.

06:38 I know it can be a little bit confusing because the arrow traditionally points to the parent class, but remember that inheritance works in only one direction.

06:49 A waitress is an employee—a specialized version of employee. That does not mean that an employee is necessarily a waitress, and so it wouldn’t make sense for the Employee class to somehow inherit from the Waitress class.

07:06 Last question: does a Cashier object work in the same way as an Employee object? Now, this one is tricky because the diagram really doesn’t tell us enough to give a definite answer. It probably does not work the same way, and that’s because the Cashier object provides its own implementation of the .work() method. This implementation overrides the parent, so if we call the .work() method on the Cashier object, it will use its own implementation of .work(), instead of that inherited from the parent.

07:45 It’s possible that this implementation is the same as Employee, which would mean that the methods are identical, but then it wouldn’t make much sense to override the .work() method in the first place. If we had left it off of the Cashier class, it would have inherited it from Employee anyway.

08:04 Generally, when you see a method in a child class that looks identical to a method in its parent, it’s a good sign that the child provides a different specialized implementation of that method.

Francesco Macrì on Aug. 21, 2020

Excellent explanations! Thank you! The short tests at the end of the chapter are very useful for checking whether one has understood the principles.

Become a Member to join the conversation.