Inheritance and Subclasses
Overview
Inheritance allows one class to reuse and extend the behavior of another. You'll practice creating subclasses that inherit methods and attributes while adding their own unique features, reducing code duplication and building hierarchical relationships.
What You Will Learn in This Lesson
By the end of this lesson, you will know:
- Inheritance basics: Understand what inheritance is and how it works.
- Creating subclasses: Learn how to create a subclass that inherits from a parent class.
- Inherited methods: Discover how subclasses automatically get parent class methods.
- Adding new features: Learn how to add new methods and attributes to subclasses.
Why This Matters
Inheritance lets you avoid writing the same code over and over! Instead of copying code between similar classes, you create a parent class with common functionality, then create child classes (subclasses) that inherit that functionality and add their own unique features. This is DRY (Don't Repeat Yourself) principle in action - it makes your code cleaner, easier to maintain, and more organized!
Step 1: What is Inheritance?
Inheritance allows a class (child/subclass) to inherit attributes and methods from another class (parent/superclass):
class Animal: # Parent class
def __init__(self, name):
self.name = name
def speak(self):
return f"{self.name} makes a sound"
class Dog(Animal): # Child class inherits from Animal
pass # Inherits everything from Animal
dog = Dog("Buddy")
print(dog.speak()) # "Buddy makes a sound"
Parent Class
The parent class (also called superclass or base class) defines common attributes and methods that child classes will inherit.
Child Class
The child class (also called subclass or derived class) inherits from the parent by putting the parent name in parentheses: class Child(Parent):
Automatic Inheritance
Child classes automatically get all methods and attributes from the parent class. You don't need to rewrite them!
Key Concept: Inheritance is like genetics - a child inherits traits from their parents! A Dog class inherits the ability to speak from Animal, just like a real dog inherits traits from the animal kingdom. But dogs can also have their own unique traits!
Mini Practice #1: Basic Inheritance
Try It YourselfCreate a parent class and a child class:
What happened? The Car class inherited from Vehicle! Even though Car is empty (just pass), it automatically got the __init__ method and the start() method from Vehicle. This is the power of inheritance - code reuse!
Step 2: Adding New Methods to Subclasses
Subclasses can add their own unique methods while still inheriting parent methods:
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
return f"{self.name} makes a sound"
class Dog(Animal):
def bark(self): # New method only for Dog
return f"{self.name} barks: Woof!"
dog = Dog("Buddy")
print(dog.speak()) # Inherited from Animal
print(dog.bark()) # Unique to Dog
Inherit Parent Methods
Subclasses automatically get all methods from the parent class. You can call them directly!
Add New Methods
Subclasses can define their own methods that are unique to them. These methods don't exist in the parent class!
Best of Both
Subclasses get parent functionality AND their own unique features. This is how inheritance makes code flexible!
Step 3: Overriding Parent Methods
Subclasses can override (replace) parent methods with their own implementation:
class Animal:
def speak(self):
return "Some sound"
class Dog(Animal):
def speak(self): # Override parent's speak method
return "Woof!"
class Cat(Animal):
def speak(self): # Override parent's speak method
return "Meow!"
dog = Dog()
cat = Cat()
print(dog.speak()) # "Woof!"
print(cat.speak()) # "Meow!"
Method Overriding
When a subclass defines a method with the same name as a parent method, it overrides (replaces) the parent's version. The subclass version is used instead. This lets you customize behavior while keeping the same interface!
Mini Practice #2: Overriding Methods
Try It YourselfOverride a parent method in a subclass:
What happened? The Rectangle class overrode the area() method from Shape. When you call rect.area(), it uses the Rectangle's version (which calculates width × height) instead of the Shape's version (which returns 0). This is method overriding!
Step 4: Multiple Levels of Inheritance
You can create inheritance chains with multiple levels:
class Animal:
def __init__(self, name):
self.name = name
class Mammal(Animal): # Inherits from Animal
def breathe(self):
return "Breathes air"
class Dog(Mammal): # Inherits from Mammal (which inherits from Animal)
def bark(self):
return "Woof!"
dog = Dog("Buddy")
print(dog.name) # From Animal
print(dog.breathe()) # From Mammal
print(dog.bark()) # From Dog
Remember: Inheritance can go multiple levels deep! A class can inherit from a class that inherits from another class. Each level adds more functionality, creating a hierarchy of classes!
End-of-Lesson Exercises
Exercise 1: Create a Subclass
Create a parent class Person with __init__(self, name) and method introduce(self) that returns "Hi, I'm {name}". Create a subclass Student that inherits from Person. Create a Student object and call introduce().
Define class Person, create Student(Person), create Student object, call introduce.
Exercise 2: Override a Method
Create a parent class Animal with method make_sound(self) that returns "Some sound". Create a subclass Dog that overrides make_sound to return "Woof!". Create a Dog object and call make_sound().
Define class Animal with make_sound, create Dog(Animal) that overrides make_sound, create Dog object, call make_sound.