Concepts / Using super() for Parent Class Access

Using super() for Parent Class Access

A base class defines shared attributes and methods; derived classes inherit from it and add their own specialized features.

  • Programming
Interactive lab

Try it: Inheritance and Method Lookup

How a subclass inherits from its parent, how Python finds an attribute by walking the instance, then the class's method resolution order up to object, how overriding and super() work, why the same call does different things on different objects (polymorphism), and what isinstance / issubclass check.

How it works

  1. class Dog(Animal) gives Dog the MRO Dog → Animal → object; Puppy(Dog) gives Puppy → Dog → Animal → object.
  2. obj.name searches obj.__dict__, then each class of type(obj).__mro__ in order; the first class that defines the name wins, so a subclass method overrides the parent's.
  3. super().method() starts the search in the class after the one the current method was defined in, e.g. to run the parent's __init__.
  4. Calling the same method on a list of different objects runs each object's own version (polymorphism).
  5. isinstance(obj, C) is True when C is in type(obj).__mro__; if no class has the name, Python raises AttributeError.

Default run (63 steps): Ready: Animal, Dog, Cat and Puppy, then the statements you picked. Each attribute is searched along the class's MRO. … Finished. Printed: Rex the dog says Woof / Tom the cat says Meow / Bo the dog says Woof! / True / Puppy / Dog / Animal / object.

Simplified: The lab's own small Python interpreter runs a fixed, hand-written script (you choose the variant and the values, never the code); nothing is executed as real Python. Every script was run in CPython 3.12 with the same inputs and the lab reproduces its output and error messages. Single inheritance only (the lab's MRO code is Python's C3 algorithm, but no class here has two parents).

Educational simulation

Loading the simulation…

One Object, Two Layers

A derived class often needs to do two jobs when an object is created: initialize the information shared by every object in the family, and then initialize information specific to the derived class. A base class provides the shared attributes and methods. The derived class inherits those features and adds specialized ones. The purpose of super() is to let the derived class use the parent implementation instead of copying its work.

SchoolMembername, age, tell()Teachersalary, tell()Studentmarks, tell()base class ofbase class of
What does a subclass inherit from its base class, and where do subclass-specific features fit?

The Initialization Handoff

When a Teacher object is created, Python begins with Teacher.__init__. The derived initializer first calls the base initializer through super().__init__(name, age). Control moves to SchoolMember.__init__, which initializes the shared name and age attributes. After that call finishes, control returns to Teacher.__init__, where salary is initialized. The important order is shared initialization first, specialized initialization second.

Code walkthrough
class SchoolMember:
    def __init__(self, name, age):
        self.name = name
        self.age = age
        print("Initialized SchoolMember:", name)

class Teacher(SchoolMember):
    def __init__(self, name, age, salary):
        super().__init__(name, age)
        self.salary = salary
        print("Initialized Teacher:", name)

teacher = Teacher("Mrs. Shrividya", 40, 30000)
  1. 1
    The SchoolMember initializer receives name and age and stores them on the object.
  2. 2
    The Teacher initializer receives the shared values plus salary.
  3. 3
    super().__init__(name, age) transfers the shared initialization work to SchoolMember.
  4. 4
    After the parent initializer returns, Teacher stores salary.
  5. 5
    The messages show the parent initialization completing before the derived initialization.
  • SchoolMember stores the attributes shared by school members.
  • Teacher inherits from SchoolMember.
  • super().__init__ calls the inherited initializer before salary is added.
  • Creating the Teacher starts the initialization sequence.
Teacher(...)object creationTeacher.__init__receives name, age, salarySchoolMember.__init__sets name, agesalarysets teacher-specific datacallssuper().__init__returns, then continues
When a Teacher is instantiated, how does control move from the subclass initializer to the parent initializer and back?
Output
Initialized SchoolMember: Mrs. Shrividya
Initialized Teacher: Mrs. Shrividya

Extending an Inherited Method

A derived class can redefine a method that already exists in the base class. This is method overriding: the derived version replaces the parent version when the method is called on an object of the derived type. The derived method can either provide completely different behavior or call the parent version first and then add specialized behavior. With super().tell(), Teacher can reuse the shared name-and-age display before adding salary, while Student can reuse the same display before adding marks.

Method designWhat happensSchool example
Inherited unchangedThe derived object uses the base implementationA derived class uses SchoolMember.tell without redefining it
OverriddenThe derived class supplies its own implementationTeacher.tell or Student.tell defines specialized output
Overridden and extendedThe derived method calls the parent implementation and adds behaviorTeacher.tell displays shared details, then salary

Three ways a derived class can use a method from its base class

python
SchoolMember.tell()name and ageTeacher.tell()parent details plus salaryStudent.tell()parent details plus markssuper().tell() then addsuper().tell() then add
How does an unchanged method differ from an override and from an override that calls the parent implementation?

Shared Behavior in a Loop

Teacher and Student each have the shared name and age attributes from SchoolMember, plus their own specialized attribute. Teacher has salary; Student has marks. Both also define tell(), but each version adds different information after using the common SchoolMember behavior.

python
Output
Name: Mrs. Shrividya
Age: 40
Salary: 30000
Name: Asha
Age: 16
Marks: 92

The loop makes the same member.tell() call for both objects. Python uses the appropriate implementation for the object: Teacher.tell() for the Teacher object and Student.tell() for the Student object. This is polymorphism. It lets code work with multiple derived classes without checking whether each object is a Teacher or a Student.

SchoolMembername, age, shared tell()Teachersalary, specialized tell()salaryafter shared detailsStudentmarks, specialized tell()marksafter shared detailsinheritsinheritsaddsadds
How can several specialized objects reuse one base class while producing different tell() behavior?

Mistakes with Parent Access

  • Common mistake

    Defining a derived __init__ method but skipping the parent initializer

    What it looks like
    class Teacher(SchoolMember):
        def __init__(self, name, age, salary):
            self.salary = salary
    Why it fails

    The shared initialization performed by SchoolMember.__init__ is not called, so the inherited name and age setup is omitted.

    Do this instead
    Call super().__init__(name, age) before setting salary.
  • Common mistake

    Replacing a parent method when the intention was to extend it

    What it looks like
    def tell(self):
        print("Salary:", self.salary)
    Why it fails

    This derived implementation does not perform the shared display behavior from SchoolMember.tell().

    Do this instead

    Call super().tell() first, then add the salary-specific output.

  • Common mistake

    Copying shared initialization into every derived class

    What it looks like

    Setting name and age separately in both Teacher and Student instead of using SchoolMember.__init__.

    Why it fails

    The shared setup is duplicated rather than defined once in the base class.

    Do this instead

    Keep common attributes in the base initializer and invoke it from each derived initializer.

  • Common mistake

    Assuming every object uses exactly the base version of an overridden method

    What it looks like

    Expecting member.tell() to produce identical output for Teacher and Student.

    Why it fails

    Teacher and Student define their own tell() methods, so the same call produces type-specific behavior.

    Do this instead

    Remember that the appropriate derived implementation runs for each object.

Best practice

Put attributes and methods shared by all members in the base class. In each derived class, call the parent initializer for shared setup, then add only the attributes and behavior that make that class specialized.

Practice the Call Order

What do you think happens?

In what order will the initialization messages appear when this object is created?

  • Initialized Teacher, then Initialized SchoolMember

  • Initialized SchoolMember, then Initialized Teacher

  • Only Initialized Teacher

  • Only Initialized SchoolMember

Reveal answer
Answer:

Initialized SchoolMember, then Initialized Teacher

Teacher.__init__ calls super().__init__ first. The SchoolMember initializer completes before Teacher continues with its own initialization.

MEDIUM

Create a third derived class named Administrator. Give it a department attribute, initialize the shared name and age through super().__init__, and override tell() so it calls super().tell() before displaying the department.

Hints
  • Make Administrator inherit from SchoolMember.
  • The initializer should receive name, age, and department.
  • The overridden tell() method should call super().tell() before displaying department.
Worked example

Tracing a Student object

A Student is created with a name, age, and marks. What does the object receive from SchoolMember, and what does Student add?

  1. 1
    Start with Student.__init__

    The derived initializer receives the shared name and age values together with the Student-specific marks value.

  2. 2
    Call the parent initializer

    super().__init__(name, age) sends the shared values to SchoolMember.__init__, which initializes name and age.

  3. 3
    Add specialized data

    Student then initializes marks on the same object.

  4. 4
    Call tell()

    Student.tell() can call super().tell() for the shared details and then display marks.

Result

The Student object has the inherited name and age attributes plus its own marks attribute, and its tell() method can combine shared and specialized behavior.

Key Takeaways

  1. 1
    A base class defines functionality shared by related objects, while a derived class inherits and specializes that functionality.
  2. 2
    A derived __init__ method should call the parent initializer through super() so inherited attributes are initialized.
  3. 3
    A derived method can override a parent method completely or call super() to extend the parent behavior.
  4. 4
    Teacher and Student can share SchoolMember functionality while adding salary and marks respectively.
  5. 5
    Polymorphism allows the same member.tell() call to produce the appropriate behavior for each derived object.

At a glance

  • Base classes hold common attributes and methods; derived classes inherit them and add specialized features.
  • Use super().__init__ in a derived initializer to perform the parent class setup before derived-class setup.
  • Use super().method_name() when an overridden method should preserve the parent behavior and add more behavior.
  • Multiple derived classes can share one base implementation while producing different results through polymorphism.

Related concepts

More concepts starting with U