5️⃣

12.5 Inheritance

Inheritance

Classes in Python can inherit the attributes and procedures (fields and methods) of another class. This is done by putting the parent class name in parenthesis in front of the class declaration as shown:

# Inheritance in coding is when one "child" class receives
# all of the methods and attributes of another "parent" class


class Test:
    def __init__(self):
        self.x = 0


# class Derived_Test inherits from class Test
class Derived_Test(Test):
    def __init__(self):
        Test.__init__(self)  # do Test's __init__ method
        # Test's __init__ gives Derived_Test the attribute 'x'
        self.y = 1


b = Derived_Test()

# Derived_Test now has an attribute "x", even though
# it originally didn't
print(b.x, b.y)

View code on GitHub.

💡

Although you can explicitly state the class that you want to do the __init__ method from like the above example, we generally use super() in its place. When you use super(), you don't need to pass self in as a parameter in the __init__ method (or any method). In the above example, we'd do super().__init__() instead of Test.__init__(self).

As you can see from the example above, Derived_Test is inheriting from Test. You can tell because Derived_Test has (Test) next to it. In programming terms, the class that is being inherited from is called the parent class while the class that inherits is called the child class.

Why would you want to use inheritance?

  • It allows for you to reuse code
  • It's more efficient for the programmer
    • In the example above, we just did Test's __init__ method and didn't have to explicitly define an x attribute for Derived_Test

What can you inherit?

You can inherit the attributes and methods of the parent class. This brings up the question: "Can you override the parent class's attributes and methods?" The answer is yes, you can do so. Here's an example of that.

class Furniture:
	def __init__(self):
		self.built = True
		self.material = "nothing"

class Sofa(Furniture):
	def __init__(self):
		super().__init__()  # sets built to True
		self.material = "comfy stuff"  # this overrides Furniture's material
		self.comfy = True
	def destroy(self):
		self.built = False

lazy_boy_couch = Sofa()
print(lazy_boy_couch.material)  # prints "comfy stuff" instead
 # of 'nothing' since we overrode it

lazy_boy_couch.destroy()
print(lazy_boy_couch.built)  # would print False since we set it to False
💡

The above just shows overriding attributes. Our last example, below, shows overriding methods.

One more Example

Just in case you need it, here's one more example of inheritance. This time, we used more concrete objects that way you can grasp the concept better.

class bird:
	def __init__(self, wingspan):
		self.living = True  # all birds will be living
		self.wingspan = wingspan  # wingspan will be set to whatever is provided
	def fly(self):
		print("it's flying")
	def eat(self):
		print("it's eating")

class penguin(bird):  # penguing is a child of bird
	def __init__(self, wingspan):  # since it's a child of bird,
		# it needs to take at least as many parameters as bird

		super().__init__(wingspan)  # passes wingspan to bird that
		# way bird can complete its init (which needs a provided wingspan)

	def fly(self):
		# this is an example of overriding a method
		# instead of fly doing what bird's fly method does,
		# it will do the following instead
		print("penguins can't fly")


emperor_peng = penguin(30)  # 30 is the wingspan

emperor_peng.eat()  # we didn't define it inside penguin, but
# penguin inherited it from bird. It will print "it's eating"

emperor_peng.fly()  # we overrode it from bird, so it will
# do penguin's fly, which is printing "penguins can't fly"

print(emperor_peng.wingspan)  # will print 30. This is because
# we passed 30 to the penguin class as the wingspan. The penguin
# class then passed 30 as the wingspan to super().__init__, or bird's init
# So, bird used wingspan, which was 30, to set our penguin's wingspan to 30

print(emperor_peng.living)  # will print True since bird's init sets it to True
💡

Technically, you don't have to do super.__init__() whenever you make a child class. However, it generally is used because, without doing that, the class would only inherit the methods and none of the attributes defined inside the __init__ function.

Practice

Food Class

Create a Food class with 4 instance attributes: name, calories, grams_of_protein, and grams_of_fat.

It should have 2 methods:

  • an eat method that prints "You are eating" and the name of the food
  • a burn method that prints "You burned [x] calories" where [x] is the number of calories in the food

Then, create a JunkFood subclass and a Meal subclass. Both subclasses should inherit from Food class. The JunkFood subclass should have an additional attribute for the grams of sugar contained in the food, and the Meal subclass should have an additional attribute for the mg of sodium it contains.

Finally, create a list called snacks and fill it with at least 3 junk foods. Then, create a list called meals and fill it with at least 3 meals. Then, use Python to show that you ate all the foods in both lists and burned off one meal (pick the meal randomly). Display the total number of calories, grams of protein, grams of fat, grams of sugar, and mg of sodium that you ate (the total for all the foods in both lists).

Buildings

Create a class building. It should have a build method that prints:

"under construction..."

"built"

It should also have an __init__ method that runs the build method (basically the __init__ method will call the build method). The __init__ method should also set an attribute built to True.

Next, create a class library. It should be a child class of building. Its __init__ method should run building's __init__ method. It should also create an empty list called books. library should also have a restock method. that asks the user for a book, prints "bough %s" where %s is the book's name, and appends the book to the library's list books. Lastly, library should also have a method catalog that prints all the library's books on separate lines.

Finally, instantiate the library class. If you did it right, you should see "under construction..." and "built"!

Previous Section

Next Section

⚖️

Copyright © 2021 Code 4 Tomorrow. All rights reserved. The code in this course is licensed under the MIT License. If you would like to use content from any of our courses, you must obtain our explicit written permission and provide credit. Please contact classes@code4tomorrow.org for inquiries.