Python tutorials > Object-Oriented Programming (OOP) > Inheritance > What are super/subclasses?

What are super/subclasses?

In object-oriented programming (OOP), inheritance allows you to create new classes based on existing classes. This fosters code reusability and promotes a hierarchical relationship between classes. The core concepts are superclasses (also known as parent classes or base classes) and subclasses (also known as child classes or derived classes). This tutorial will explain superclasses and subclasses in Python.

Superclasses (Parent Classes)

A superclass is the class whose properties and methods are inherited by another class. It represents a more general concept. Think of it as the blueprint from which other classes are built. It defines the common characteristics that its subclasses will share.

Subclasses (Child Classes)

A subclass is a class that inherits properties and methods from a superclass. It represents a more specific concept. A subclass extends or specializes the superclass, adding new functionality or modifying existing behavior. A subclass can also override methods of the superclass, providing a specific implementation for the subclass.

Basic Example: Animal and Dog

In this example, Animal is the superclass, and Dog is the subclass. The Dog class inherits the name attribute from the Animal class and also has its own implementation of the speak method, overriding the superclass's method.

class Animal:
    def __init__(self, name):
        self.name = name

    def speak(self):
        return "Generic animal sound"

class Dog(Animal):
    def speak(self):
        return "Woof!"

mydog = Dog("Buddy")
print(mydog.name) # Output: Buddy
print(mydog.speak()) # Output: Woof!

animal = Animal("Generic Animal")
print(animal.speak()) # Output: Generic animal sound

Concepts Behind the Snippet

The core idea is that the Dog is a type of Animal. Inheritance expresses this 'is-a' relationship. The Dog class automatically gets all the attributes and methods defined in the Animal class, saving you from writing the same code again. Overriding allows the subclass to customize the behavior inherited from the superclass.

Real-Life Use Case Section

Consider a scenario where you are building a GUI application. You might have a base class called Widget that defines common properties like position, size, and color. You can then create subclasses like Button, Textbox, and Label that inherit these properties from Widget and add their own specific functionality. Another example might be a game, where you have a Character base class, and subclasses like Player, Enemy, and NPC.

Best Practices

  • Favor Composition over Inheritance: While inheritance is useful, overusing it can lead to rigid class hierarchies. Consider using composition (building classes by combining instances of other classes) when appropriate.
  • Keep Class Hierarchies Shallow: Deep inheritance hierarchies can be difficult to understand and maintain. Try to keep your class hierarchies relatively shallow.
  • Use Abstract Base Classes: For interfaces or common functionality, use abstract base classes to enforce a certain structure among subclasses.
  • Follow the Liskov Substitution Principle: Subclasses should be substitutable for their superclasses without altering the correctness of the program.

Interview Tip

Be prepared to explain the concepts of superclasses and subclasses, inheritance, and overriding. Be able to discuss the advantages and disadvantages of inheritance, and when it is appropriate to use it. Mention the 'is-a' relationship, and give real-world examples of how inheritance is used.

When to Use Them

Use inheritance when you have a clear 'is-a' relationship between classes. When you want to reuse code from an existing class and add or modify its behavior. Use it to create a hierarchy of related classes with shared functionality.

Memory Footprint

Inheritance itself does not add significant memory overhead. Each subclass instance will store the attributes specific to it, in addition to the inherited attributes. The methods are typically stored once per class, not per instance. However, deep inheritance hierarchies can indirectly increase memory usage due to the complexity of the class structure and potential for duplicated attributes or methods due to poor design.

Alternatives

Composition: Instead of inheriting from a superclass, a class can contain instances of other classes and delegate functionality to them. This promotes flexibility and avoids the tight coupling associated with inheritance.

Mixins: Mixins are small classes that provide specific functionality and can be combined with other classes through multiple inheritance. This can be a cleaner alternative to deep inheritance hierarchies.

Interfaces (Abstract Base Classes): Define a contract that classes must adhere to, without providing implementation details. This allows for polymorphism and loose coupling.

Pros

  • Code Reusability: Reduces code duplication by inheriting common functionality from superclasses.
  • Improved Organization: Creates a hierarchical structure that reflects the relationships between classes.
  • Polymorphism: Allows objects of different classes to be treated as objects of a common superclass.
  • Extensibility: Makes it easier to add new functionality by creating new subclasses.

Cons

  • Tight Coupling: Subclasses are tightly coupled to their superclasses, which can make it difficult to modify the superclass without affecting the subclasses.
  • Fragile Base Class Problem: Changes to the superclass can unintentionally break subclasses.
  • Complex Hierarchies: Deep inheritance hierarchies can be difficult to understand and maintain.
  • Potential for Code Bloat: Subclasses may inherit methods or attributes that they don't need, leading to code bloat.

FAQ

  • What happens if a subclass defines a method with the same name as a method in the superclass?

    The subclass's method overrides the superclass's method. When you call that method on an instance of the subclass, the subclass's implementation will be executed.

  • Can a class inherit from multiple superclasses?

    Yes, Python supports multiple inheritance. A class can inherit from multiple superclasses, inheriting their attributes and methods. However, multiple inheritance can lead to complex class hierarchies and potential conflicts (the 'diamond problem').

  • What is the super() function used for?

    The super() function is used to call methods from the superclass from within the subclass. This is often used to extend the functionality of a superclass method without completely overriding it. For example, calling the superclass's __init__ method to initialize inherited attributes.