Python > Object-Oriented Programming (OOP) in Python > Inheritance > Single Inheritance

Single Inheritance: Vehicle and Car

This code demonstrates how a Car class inherits from a Vehicle class, showcasing single inheritance. The Car class adds specific attributes like model while inheriting common attributes and methods from the Vehicle class. It also overrides the start_engine method.

Code Example

The Vehicle class defines common attributes (make, color) and methods (start_engine, stop_engine) for all vehicles. The Car class inherits from Vehicle, adding the model attribute and overriding the start_engine method to provide a car-specific implementation. The super().__init__(make, color) call ensures that the inherited attributes are properly initialized.

class Vehicle:
    def __init__(self, make, color):
        self.make = make
        self.color = color

    def start_engine(self):
        return "Engine starting..."

    def stop_engine(self):
        return "Engine stopping..."

class Car(Vehicle):
    def __init__(self, make, color, model):
        super().__init__(make, color)
        self.model = model

    def start_engine(self):
        return "Car engine starting... Vroom Vroom!"

my_car = Car("Toyota", "Red", "Camry")
print(my_car.make)
print(my_car.color)
print(my_car.model)
print(my_car.start_engine())
print(my_car.stop_engine())

Explanation of Key Concepts

Inheritance: Enables a class to inherit properties and behaviors from another class, fostering code reuse and a hierarchical structure.

Single Inheritance: Restricts a class to inherit from only one parent class, simplifying the inheritance structure.

Method Overriding: Allows a subclass to provide a specific implementation of a method that is already defined in its superclass.

Real-World Application

Consider a game development scenario. You might have a GameObject class with attributes like position, rotation, and methods like update(), render(). Subclasses like Player, Enemy, and Item could inherit from GameObject. The Player class might add attributes like health, score and override the update() method to handle player-specific movement and actions. This allows you to efficiently create different game entities while reusing common functionality from the GameObject class.

Guidelines

  • Maintain a clear 'is-a' relationship: Ensure that inheritance is used only when there is a genuine 'is-a' relationship between classes.
  • Avoid deep inheritance hierarchies: Keep the inheritance hierarchy shallow to improve readability and maintainability.
  • Favor composition over inheritance when appropriate: Consider composition as an alternative to inheritance when dealing with complex relationships.

Interview insights

Be prepared to articulate the trade-offs between inheritance and composition. Understand when each approach is more appropriate. Explain how inheritance promotes code reuse and polymorphism but can also lead to increased complexity. Demonstrate your ability to design classes using inheritance effectively.

Appropriate usage

Use single inheritance to create a specific version of something more general. It helps establish a structure and reduces code repetition, by extending the base class.

Memory Usage

Inheritance adds extra memory for each child because there are new methods and properties added to the child class.

Alternative Methods

Composition: Instead of inheriting, a class can contain instances of other classes as attributes. This provides a more flexible way to combine functionality from multiple classes.

Interfaces: Define a set of methods that a class must implement. This allows you to enforce a specific interface without creating a strict inheritance hierarchy.

Advantages

  • Reduces code duplication: Inherited attributes and methods don't need to be rewritten in subclasses.
  • Establishes clear relationships: Makes the relationship between classes explicit and easy to understand.
  • Promotes polymorphism: Enables objects of different classes to be treated as objects of a common type.

Disadvantages

  • Can lead to tight coupling: Subclasses are tightly coupled to their superclasses, making it difficult to modify the superclass without affecting the subclasses.
  • Can create complex hierarchies: Deep inheritance hierarchies can become difficult to understand and maintain.
  • May not always be the best solution: Sometimes composition is a more appropriate approach.

FAQ

  • Why use super().__init__() in the Car class?

    It calls the constructor of the parent class (Vehicle) to initialize the make and color attributes, ensuring that the inherited attributes are properly initialized.
  • What happens if I don't call super().__init__()?

    The attributes inherited from the parent class (make and color in this case) will not be initialized, potentially leading to unexpected behavior or errors.
  • Can I inherit from multiple classes in Python?

    Yes, Python supports multiple inheritance, where a class can inherit from multiple parent classes. However, multiple inheritance can lead to increased complexity and is generally less common than single inheritance.