Concepts / Working with Multiple Levels of Inheritance

Working with Multiple Levels of Inheritance

A child class extends a parent class using the syntax class ChildClass(ParentClass):, inheriting all parent variables and methods automatically.

  • Programming

One Object, Several Sources of Behavior

A child class does not start from nothing. It extends a parent class, automatically receiving the parent's variables and methods while also gaining the ability to define additional features. This means one child-class instance can combine inherited behavior with behavior introduced specifically by the child.

The relationship is one-way: the child inherits from the parent, but the parent does not inherit from the child.

Following the Class Hierarchy

Inheritance syntax places the parent class name in parentheses after the child class name. The form class ChildClass(ParentClass): tells Python that ChildClass extends ParentClass. The parent sits above the child in the hierarchy. The child receives the parent's variables and methods automatically, so an instance of the child can use inherited features as well as features defined directly in the child.

inherits fromcreatesPartyAnimalname, party()CricketFanpoints, six()jname, party(), points,six()
What does a child inherit from its parent, and what does it add for itself?

In the source example, CricketFan is the child class and PartyAnimal is the parent class. PartyAnimal provides name and party(). CricketFan adds points and six(). An instance named j therefore has access to all four features: the inherited name and party(), plus the child-defined points and six().

Initializing Parent and Child State

A child class often needs to initialize two groups of variables: the variables required by the parent and the new variables required by the child. The child class can use super() inside its __init__ method to call the parent class's __init__ method. This lets the parent complete its own setup before the child adds child-specific variables.

callssuper()returns, then setsCreate CricketFanchild objectCricketFan.__init__starts child setupPartyAnimal.__init__initializes namepointschild attribute
When a child object is created, how does control move through the child and parent initializers?

class PartyAnimal: def __init__(self, name): self.name = name class CricketFan(PartyAnimal): def __init__(self, name, points): super().__init__(name) self.points = points def six(self): pass

Keeping Inherited Behavior and Adding More

Extending a class does not remove the parent's functionality. CricketFan keeps access to the inherited party() method and adds its own six() method. The same combination applies to variables: name comes from the parent setup, while points is introduced by the child.

FeatureWhere it is definedAvailable on CricketFan instance
namePartyAnimalYes, inherited
party()PartyAnimalYes, inherited
pointsCricketFanYes, child-defined
six()CricketFanYes, child-defined

Tracing the CricketFan instance

Determine which features are available on an instance j of CricketFan.

Identify the parent: CricketFan extends PartyAnimal, so PartyAnimal is the source of inherited features.

Collect inherited features: The instance receives name and party() from PartyAnimal.

Collect child features: CricketFan adds points and six().

Combine the results: The child instance can access both groups of features.

j has name and party() from PartyAnimal, plus points and six() from CricketFan.

Mistakes in Parent Initialization

  • Treating the child as if it receives only its own variables and methods.

    A child instance contains inherited variables and methods as well as child-defined features.

    Fix: Check both the parent and child class when listing what the instance can access.

  • Defining the child without naming its parent in parentheses.

    The parenthesized class name tells Python which class the new class extends.

    Fix: Place the parent class name in parentheses after the child class name.

  • Setting child variables before calling the parent initializer.

    The source guidance requires the parent to be fully initialized first.

    Fix: Call super().__init__() before setting up child-specific variables.

  • Expecting the parent to inherit child features.

    Inheritance moves from parent to child, not from child to parent.

    Fix: Treat the relationship as one-way: the child receives parent features.

Practice the Inheritance Trace

EASY

Suppose Player is a parent class with a name variable and a play() method. Suppose CricketPlayer extends Player and adds a points variable and a score() method. List the features an instance of CricketPlayer should contain, and state which class provides each feature.

Hints
  • Separate features defined by the parent from features added by the child.
  • Remember that the child instance combines inherited and child-defined features.
  • Use the PartyAnimal and CricketFan example as a model.
MEDIUM

Explain why a child initializer should call super().__init__() before assigning its own variables. In your explanation, identify what setup belongs to the parent and what setup belongs to the child.

Hints
  • The parent initializer prepares the parent class's variables.
  • The child initializer can add new variables after the parent setup is complete.

Key Takeaways

  1. Use class ChildClass(ParentClass): to define a child that extends a parent.
  2. A child inherits the parent's variables and methods automatically.
  3. Use super().__init__() inside the child initializer to run the parent initializer.
  4. Call the parent initializer before setting child-specific variables.
  5. A child instance combines inherited features with new variables and methods defined by the child.

Key Takeaways

  • Inheritance creates a one-way parent-to-child relationship.
  • The child class receives the parent's variables and methods and can add its own.
  • The super() function lets the child call the parent class's __init__ method.
  • Parent initialization should happen before child-specific setup.
  • An instance of the child class combines inherited and newly defined functionality.