Skip to main content
Engineering LibreTexts

13.4: Hierarchical Inheritance

  • Page ID
    117609
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)

    \( \newcommand{\dsum}{\displaystyle\sum\limits} \)

    \( \newcommand{\dint}{\displaystyle\int\limits} \)

    \( \newcommand{\dlim}{\displaystyle\lim\limits} \)

    \( \newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\)

    ( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\)

    \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)

    \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\)

    \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)

    \( \newcommand{\Span}{\mathrm{span}}\)

    \( \newcommand{\id}{\mathrm{id}}\)

    \( \newcommand{\Span}{\mathrm{span}}\)

    \( \newcommand{\kernel}{\mathrm{null}\,}\)

    \( \newcommand{\range}{\mathrm{range}\,}\)

    \( \newcommand{\RealPart}{\mathrm{Re}}\)

    \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)

    \( \newcommand{\Argument}{\mathrm{Arg}}\)

    \( \newcommand{\norm}[1]{\| #1 \|}\)

    \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)

    \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    \( \newcommand{\vectorA}[1]{\vec{#1}}      % arrow\)

    \( \newcommand{\vectorAt}[1]{\vec{\text{#1}}}      % arrow\)

    \( \newcommand{\vectorB}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vectorC}[1]{\textbf{#1}} \)

    \( \newcommand{\vectorD}[1]{\overrightarrow{#1}} \)

    \( \newcommand{\vectorDt}[1]{\overrightarrow{\text{#1}}} \)

    \( \newcommand{\vectE}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash{\mathbf {#1}}}} \)

    \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \(\newcommand{\longvect}{\overrightarrow}\)

    \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)

    \(\newcommand{\avec}{\mathbf a}\) \(\newcommand{\bvec}{\mathbf b}\) \(\newcommand{\cvec}{\mathbf c}\) \(\newcommand{\dvec}{\mathbf d}\) \(\newcommand{\dtil}{\widetilde{\mathbf d}}\) \(\newcommand{\evec}{\mathbf e}\) \(\newcommand{\fvec}{\mathbf f}\) \(\newcommand{\nvec}{\mathbf n}\) \(\newcommand{\pvec}{\mathbf p}\) \(\newcommand{\qvec}{\mathbf q}\) \(\newcommand{\svec}{\mathbf s}\) \(\newcommand{\tvec}{\mathbf t}\) \(\newcommand{\uvec}{\mathbf u}\) \(\newcommand{\vvec}{\mathbf v}\) \(\newcommand{\wvec}{\mathbf w}\) \(\newcommand{\xvec}{\mathbf x}\) \(\newcommand{\yvec}{\mathbf y}\) \(\newcommand{\zvec}{\mathbf z}\) \(\newcommand{\rvec}{\mathbf r}\) \(\newcommand{\mvec}{\mathbf m}\) \(\newcommand{\zerovec}{\mathbf 0}\) \(\newcommand{\onevec}{\mathbf 1}\) \(\newcommand{\real}{\mathbb R}\) \(\newcommand{\twovec}[2]{\left[\begin{array}{r}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\ctwovec}[2]{\left[\begin{array}{c}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\threevec}[3]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\cthreevec}[3]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\fourvec}[4]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\cfourvec}[4]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\fivevec}[5]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\cfivevec}[5]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\mattwo}[4]{\left[\begin{array}{rr}#1 \amp #2 \\ #3 \amp #4 \\ \end{array}\right]}\) \(\newcommand{\laspan}[1]{\text{Span}\{#1\}}\) \(\newcommand{\bcal}{\cal B}\) \(\newcommand{\ccal}{\cal C}\) \(\newcommand{\scal}{\cal S}\) \(\newcommand{\wcal}{\cal W}\) \(\newcommand{\ecal}{\cal E}\) \(\newcommand{\coords}[2]{\left\{#1\right\}_{#2}}\) \(\newcommand{\gray}[1]{\color{gray}{#1}}\) \(\newcommand{\lgray}[1]{\color{lightgray}{#1}}\) \(\newcommand{\rank}{\operatorname{rank}}\) \(\newcommand{\row}{\text{Row}}\) \(\newcommand{\col}{\text{Col}}\) \(\renewcommand{\row}{\text{Row}}\) \(\newcommand{\nul}{\text{Nul}}\) \(\newcommand{\var}{\text{Var}}\) \(\newcommand{\corr}{\text{corr}}\) \(\newcommand{\len}[1]{\left|#1\right|}\) \(\newcommand{\bbar}{\overline{\bvec}}\) \(\newcommand{\bhat}{\widehat{\bvec}}\) \(\newcommand{\bperp}{\bvec^\perp}\) \(\newcommand{\xhat}{\widehat{\xvec}}\) \(\newcommand{\vhat}{\widehat{\vvec}}\) \(\newcommand{\uhat}{\widehat{\uvec}}\) \(\newcommand{\what}{\widehat{\wvec}}\) \(\newcommand{\Sighat}{\widehat{\Sigma}}\) \(\newcommand{\lt}{<}\) \(\newcommand{\gt}{>}\) \(\newcommand{\amp}{&}\) \(\definecolor{fillinmathshade}{gray}{0.9}\)
    Learning Objectives

    By the end of this section you should be able to

    • Label relationships between classes as types of inheritance.
    • Construct classes that form hierarchical inheritance.

    Hierarchical inheritance basics

    Hierarchical inheritance is a type of inheritance in which multiple classes inherit from a single superclass. Multilevel inheritance is a type of inheritance in which a subclass becomes the superclass for another class. Combining hierarchical and multilevel inheritance creates a tree-like organization of classes.

    Checkpoint: Hierarchical organization and types of inheritance
    Concepts in Practice \(\PageIndex{1}\): Hierarchical organization

    Which is an example of hierarchical inheritance?

    1. Class B inherits from Class A
      Class C inherits from Class A
    2. Class B inherits from Class A
      Class C inherits from Class B
    3. Class B inherits from Class A
      Class C inherits from Class D
    Answer

    a. Class A is the superclass for Class B and Class C.

    Concepts in Practice \(\PageIndex{2}\): Hierarchical organization

    Which group of classes is hierarchical inheritance appropriate for?

    1. Cat, Dog, Bird
    2. Employee, Developer, SalesRep
    3. Dessert, BakedGood, ApplePie
    Answer

    b. Employee would be an appropriate superclass for Developer and SalesRep. Developer and SalesRep are not directly related.

    Implementing hierarchical inheritance

    Multiple classes can inherit from a single class by simply including the superclass name in each subclass definition.

    Example 13.4: Choir members
        class ChoirMember:
          def display(self):
            print("Current choir member")
    
        class Soprano(ChoirMember):
          def display(self):
            super().display()
            print("Part: Soprano")
    
        class Soprano1(Soprano):
          def display(self):
            super().display()
            print("Division: Soprano 1")
    
        class Alto(ChoirMember):
          def display(self):
            super().display()
            print("Part: Alto")
    
        class Tenor(ChoirMember):
          def display(self):
            super().display()
            print("Part: Tenor")
    
        class Bass(ChoirMember):
          def display(self):
            super().display()
            print("Part: Bass")
    
        mem_10 = Alto()
        mem_13 = Tenor()
        mem_15 = Soprano1()
    
        mem_10.display()
        print()
        mem_13.display()
        print()
        mem_15.display()

    The code's output is:

        Current choir member
        Part: Alto
    
        Current choir member
        Part: Tenor
    
        Current choir member
        Part: Soprano
        Division: Soprano 1
    Concepts in Practice: Implementing hierarchical inheritance

    Consider the program:

        class A:
          def __init__(self, a_attr=0):
            self.a_attr = a_attr
    
        class B(A):
          def __init__(self, a_attr=0, b_attr=0):
            super().__init__(a_attr)
            self.b_attr = b_attr
    
        class C(A):
          def __init__(self, a_attr=0, c_attr=0):
            super().__init__(a_attr)
            self.c_attr = c_attr
    
        class D(B):
          def __init__(self, a_attr=0, b_attr=0, d_attr=0):
            super().__init__(a_attr, b_attr)
            self.d_attr = d_attr
        
        b_inst = B(2)
        c_inst = C(c_attr=4)
        d_inst = D(6, 7)
    
    Concepts in Practice \(\PageIndex{3}\): Implementing hierarchical inheritance

    What is the value of b_inst.b_attr?

    1. 0
    2. 2
    3. Error
    Answer

    a. B(2) resolves to B(2, 0), as b_attr has a default value of 0 . a_attr is assigned with 2 .

    Concepts in Practice \(\PageIndex{4}\): Implementing hierarchical inheritance

    Which attributes does c_inst have access to?

    1. a_attr
    2. a_attr, c_attr
    3. c_attr
    Answer

    b. c_inst has access to C's instance attribute, c_attr, as well the inherited attribute from A, a_attr.

    Concepts in Practice \(\PageIndex{5}\): Implementing hierarchical inheritance

    Which attributes does d_inst have access to?

    1. b_attr, d_attr
    2. a_attr, b_attr, d_attr
    3. d_attr
    Answer

    b. D, which inherits from B, so d_inst inherits b_attr. B also inherits from A, so d_inst inherits d_attr.

    Try It: Overriding methods

    Define three classes: Instrument, Woodwind, and String.

    • Instrument has instance attribute owner, with default value of "unknown".
    • Woodwind inherits from Instrument and has instance attribute material with default value of "wood".
    • String inherits from Instrument and has instance attribute num_strings, with default value of 4.

    The output should match:

        This flute belongs to unknown and is made of silver
        This cello belongs to Bea and has 4 strings
    Interactive Code
    # Define Instrument class
    
    # Define Woodwind class
    
    # Define String class
    
    print(f"This flute belongs to {flute_1.owner} and is made of {flute_1.material}")
    print(f"This cello belongs to {cello_1.owner} and has {cello_1.num_strings} strings")
     
    Answer

    class Instrument():
    def __init__(self, name='unknown'):
    self.owner = name

    class Woodwind(Instrument):
    def __init__(self, name='unknown', material='wood'):
    super().__init__(name)
    self.material = material

    class String(Instrument):
    def __init__(self, name='unknown', num_strings=4):
    super().__init__(name)
    self.num_strings = num_strings

    flute_1 = Woodwind(material='silver')
    cello_1 = String('Bea')

    print(f"This flute belongs to {flute_1.owner} and is made of {flute_1.material}")
    print(f"This cello belongs to {cello_1.owner} and has {cello_1.num_strings} strings")


    This page titled 13.4: Hierarchical Inheritance is shared under a CC BY 4.0 license and was authored, remixed, and/or curated by OpenStax via source content that was edited to the style and standards of the LibreTexts platform.