Python Inheritance
Inheritance is a way to create a new class that is a modified version of an existing class. The new class is called the subclass, and the existing class is the superclass.
Purpose of Inheritance
The main purpose of inheritance is to reuse code from the superclass in the subclass. This allows you to create a new class with all the functionality of the superclass, and then add or modify attributes and methods as needed.
Inheritance Syntax
To create a subclass, you use the following syntax:
class SubClass(SuperClass): # attributes and methods
For example, let's say we have a superclass called Car and we want to create a subclass called ElectricCar. The syntax would be:
class Car: def __init__(self, make, model, year): self.make = make self.model = model self.year = year def full_model_name(self): return f"{self.make} {self.model}" class ElectricCar(Car): # attributes and methods
Add Attributes & Methods
In the subclass, you can add new attributes and methods, or override existing ones from the superclass. For example:
class ElectricCar(Car): def __init__(self, model, year, battery_size): super().__init__(model, year) self.battery_size = battery_size def get_range(self): if self.battery_size == 70: range = 240 elif self.battery_size == 85: range = 270 else: range = 0 return "This car can go approximately " + str(range) + " miles on a full charge."
In this example, we added a new attribute called battery_size and a new method called get_range() to the ElectricCar subclass. We also used the super() function to call the init() method of the Car superclass and initialize the model and year attributes.
Overriding
You can also override methods from the superclass in the subclass. For example:
class ElectricCar(Car): def __init__(self, model, year, battery_size): super().__init__(model, year) self.battery_size = battery_size def get_range(self): if self.battery_size == 70: range = 240 elif self.battery_size == 85: range = 270 else: range = 0 return "This car can go approximately " + str(range) + " miles on a full charge." def fill_gas_tank(self): return "This car has no gas tank."
In this example, we override the fill_gas_tank() method from the Car superclass with a new version that is specific to electric cars.
What is super()?
The super() function is a built-in function in Python that returns a temporary object of the superclass. It allows you to access the attributes and methods of the superclass in the subclass.
How to Use super()
To use the super() function, you call it with no arguments inside the subclass method. For example:
class ElectricCar(Car): def __init__(self, model, year, battery_size): super().__init__(model, year) self.battery_size = battery_size
In this example, the init() method of the ElectricCar subclass calls the init() method of the Car superclass using super().init(model, year). This initializes the model and year attributes of the ElectricCar object.
You can also use the super() function to call other methods of the superclass. For example:
class ElectricCar(Car): def __init__(self, model, year, battery_size): super().__init__(model, year) self.battery_size = battery_size def get_range(self): if self.battery_size == 70: range = 240 elif self.battery_size == 85: range = 270 else: range = 0 return "This car can go approximately " + str(range) + " miles on a full charge." def full_model_name(self): return f"EV {super().full_model_name()}
In this example, the model() method of the FakeElectricCar subclass calls the fill_gas_tank() method of the Car superclass using super().fill_gas_tank(). This allows the ElectricCar object to access the behavior of the fill_gas_tank() method from the Car superclass.
Multiple Inheritance
In Python, a subclass can also inherit from multiple superclasses. This is called multiple inheritance.
To create a subclass that inherits from multiple superclasses, you list the superclasses in parentheses separated by commas. For example:
class HybridCar(ElectricCar, Car): def __init__(self, model, year, battery_size, gas_tank_size): ElectricCar.__init__(self, model, year, battery_size) Car.__init__(self, model, year, gas_tank_size) def get_range(self): electric_range = ElectricCar.get_range(self) gas_range = Car.get_range(self) return electric_range + " " + gas_range
In this example, the HybridCar subclass inherits from both the ElectricCar and Car superclasses. It has access to all the attributes and methods of both superclasses. The init() and get_range() methods are overridden to combine the functionality of both superclasses.
Best Practices
- Use inheritance to reuse code and reduce duplication. Inheritance is a powerful tool that allows you to create a new class with all the functionality of an existing class, and then add or modify attributes and methods as needed.
- Avoid creating deep inheritance hierarchies. While inheritance can be useful for code reuse, deep inheritance hierarchies (i.e., a subclass that inherits from a subclass that inherits from a subclass, etc.) can be difficult to understand and maintain. Try to keep your inheritance hierarchy as shallow as possible.
- Use composition instead of inheritance when appropriate. Composition is another way to reuse code in which a class contains instance variables that are objects of other classes. This can be a better alternative to inheritance in some cases, especially when the relationship between the classes is more "has-a" than "is-a".
- Override methods carefully. When overriding methods in a subclass, be sure to understand the behavior of the method in the superclass and consider how you want the subclass to behave differently. Make sure to test your subclass thoroughly to ensure that the overridden methods are working as expected.
- Use the super() function wisely. The super() function is a powerful tool that allows you to access the attributes and methods of the superclass in the subclass. However, it's important to use it wisely, as it can lead to confusion if overused. In particular, be careful when calling multiple inheritance, as the order in which the superclasses are called can affect the behavior of the subclass.