Skip to main content
Engineering LibreTexts

13.3: Methods

  • Page ID
    117608
  • \( \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

    • Write overridden methods to change behavior of inherited methods.
    • Use super() to access superclass methods.
    • Identify applications of polymorphism in method and function use.

    Overriding methods

    Sometimes a programmer wants to change the functions a subclass inherits. Mint is a subclass that has the same functionality as Plant, except for one function. A subclass can override a superclass method by defining a method with the same name as the superclass method.

    Checkpoint: Overriding a superclass method
    Concepts in Practice \(\PageIndex{1}\): Overriding methods

    Suppose a programmer inherits the ContractTax class from class Tax and wants to override Tax's calc_tax(). What should the programmer do?

    1. Define another calc_tax() method in Tax.
    2. Define a calc_tax() method in ContractTax.
    3. Define a function that takes a ContractTax instance.
    Answer

    b. Overriding involves defining a subclass method that has the same name as the superclass method.

    Concepts in Practice \(\PageIndex{2}\): Overriding methods

    Which is the error in the program that attempts to override calc_tax() for ContractTaxDE?

    class Tax:
      def calc_tax(self):
        print('Calculating tax')
    
    class ContractTax(Tax):
      def calc_tax(self):
        print('Calculating contract tax')
    
    class ContractTaxDE(ContractTax):
      def calc_tax():
        print('Calculating German contract tax')
    
    my_tax = ContractTaxDE()
    my_tax.calc_tax()
    
    1. ContractTaxDE must inherit from Tax, not ContractTax.
    2. ContractTaxDE's definition of calc_tax() is missing a parameter.
    3. ContractTaxDE can't override calc_tax() since ContractTax already has.
    Answer

    b. The self parameter is missing from the overridden method's definition.

    Concepts in Practice \(\PageIndex{3}\): Overriding methods

    The following program doesn't override calc_tax(). Why?

    class Tax:
      def calc_tax(self):
        print('Calculating tax')
        total = 0 # To replace with calculation
        return total
    
    class ContractTax:
      def calc_tax(self):
        print('Calculating contract tax')
        total = 0 # To replace with calculation
        return total
    
    my_tax = ContractTax()
    my_tax.calc_tax()
    
    1. An overridden method cannot return a value.
    2. Tax doesn't specify calc_tax() can be overridden.
    3. ContractTax isn't inherited from Tax.
    Answer

    c. The class definition doesn't indicate inheritance. The definition should be class ContractTax(Tax):.

    super()

    super() is a special method that provides a temporary superclass object instance for a subclass to use. super() is commonly used to call superclass methods from a subclass. super() is commonly used in a subclass's __init__() to assign inherited instance attributes. Ex: super().__init__().

    Checkpoint: Using super() to call the superclass __init__() method
    Concepts in Practice: Using super()

    Consider the following program.

    1

    class Polygon:

    2

    def __init__(self, num_sides=3):

    3

    self.num_sides = num_sides

    4
    5

    class Rectangle(Polygon):

    6

    def __init__(self, ln=1, wd=1):

    7

    super().__init__(4)

    8

    self.length = ln

    9

    self.width = wd

    10
    11

    class Square(Rectangle):

    12

    def __init__(self, side=1):

    13

    super().__init__(side, side)

    14

    self.side = side

    15
    16

    sq_1 = Square(5)

    17

    print(sq_1.num_sides)

    Concepts in Practice \(\PageIndex{4}\): Using super()

    Line 16 executes and Square's __init__() is called on line 12. Line 13 executes and the superclass's __init__() is called. Which line does control flow move to next?

    1. 2
    2. 6
    3. 14
    Answer

    b. Square's superclass is Rectangle. Rectangle's __init__() is called on line 6.

    Concepts in Practice \(\PageIndex{5}\): Using super()

    The next line executes. Which line does control flow move to next?

    1. 2
    2. 6
    3. 14
    Answer

    a. super().__init__(4) calls the __init__() of Rectangle's superclass, Polygon. Control moves to line 3, and num_sides is initialized with 4.

    Concepts in Practice \(\PageIndex{6}\): Using super()

    The method call returns. Lines 8 and 9 execute to initialize length and width, and Rectangle's __init__() returns. Which line does control flow move to next?

    1. 12
    2. 14
    3. 17
    Answer

    b. The instance attribute side is initialized with 5.

    Concepts in Practice \(\PageIndex{7}\): Using super()

    Square's __init__() returns and control flow moves to line 17. What is the output?

    1. 3
    2. 4
    3. 5
    Answer

    b. Rectangle's __init__() always calls Polygon's __init__() with num_sides=4.

    Polymorphism

    Polymorphism is the concept of having many forms. In programming, a single name can be used for multiple functionalities. Within inheritance, polymorphism is the basis of method overriding, as multiple methods have the same name.

    Example 13.1: Polymorphism and inheritance

    The name display() maps to multiple methods. The class type of the calling object determines which display() method is executed.

        class Plant:
          def display(self):
            print("I'm a plant")
    
        class Mint(Plant):
          def display(self):
            print("I'm a mint")
    
        class Lavender(Mint):
          def display(self):
            print("I'm a lavender")
    
        mint_1 = Mint()
        mint_1.display()
    
        lavender_1 = Lavender()
        lavender_1.display()

    The code's output is:

        I'm a mint
        I'm a lavender

    Polymorphism can also be used with methods of unrelated classes. The class type of the calling object determines the method executed.

    Example 13.2: Polymorphism and methods

    Tax and ContractTax are unrelated classes that each define calc_tax(). calc_tax() isn't overridden as ContractTax isn't inherited from Tax.

        class Tax:
          def __init__(self, value):
            self.value = value
      
          def calc_tax(self):
            print("Calculating tax")
            total = 0.10 * self.value  # To replace with calculation
            return total
      
        class ContractTax:
          def __init__(self, value):
            self.value = value
      
          def calc_tax(self):
              print("Calculating contracts tax")
              total = 0.15 * self.value  # To replace with calculation
              return total
      
        my_tax = ContractTax(value=1000)  # Replace 1000 with any value
        result = my_tax.calc_tax()
        print(f"Total tax: ${result}")

    The code's output is:

        Calculating contracts tax
        Total tax: $150.00

    Polymorphism allows methods to be called with different parameter types. Many built-in operators and functions have this utility.

    Example 13.3: Polymorphism and functions

    len() can be called with multiple types, including lists and strings.

        tree_list = ["ash", "hazel", "oak", "yew"]
        tree_1 = tree_list[0]
        print(len(tree_list))
        print(len(tree_1))

    The code's output is:

        4
        3
    Concepts in Practice \(\PageIndex{8}\): Polymorphism in practice

    Consider the example. What is the output?

    class Polygon:
      def print_type(self):
        print("Polygon type")
    
    class Rectangle(Polygon):
      def print_type(self):
        print("Rectangle type")
    
    class Square(Rectangle):
      def print_type(self):
        print("Square type")
    
    sq_1 = Square()
    sq_1.print_type()
    
    1. Polygon type
    2. Rectangle type
    3. Square type
    Answer

    c. Polymorphism allows print_type() to be overridden in subclasses of Polygon.

    Concepts in Practice \(\PageIndex{9}\): Polymorphism in practice

    Which is an example of polymorphism for the multiplication operator?

    1. x = 3 * 4
      y = 3 * "la"
      
    2. x = 3 * 4
      y = str(x)
      
    3. x = 3 * 4
      y = x * x
    Answer

    a. The * operator can be used with integer operands as well as strings and other types.

    Try It: Overriding methods

    Given the Pet class, create a Bird class inherited from Pet and a Finch class inherited from Bird. Override the display() method in Bird and Finch such that the program output is:

        Pet type: Bird
        Bird type: Finch
    Interactive Code
    class Pet():
        def display(self):
            print("Clinic patient: Pet")
    
    # Define Bird class
    
    # Define Finch class
    
    bird_1 = Bird()
    bird_1.display()
    finch_1 = Finch()
    finch_1.display()
     
    Answer

    class Pet():
    def display(self):
    print("Clinic patient: Pet")

    class Bird(Pet):
    def display(self):
    print("Pet type: Bird")

    class Finch(Bird):
    def display(self):
    print("Bird type: Finch")

    bird_1 = Bird()
    bird_1.display()
    finch_1 = Finch()
    finch_1.display()

    Try It: Using super()

    Given the Employee class, create a Developer class inherited from Employee with methods __init__() and print_info() such that:

    __init__()

    • Uses super() to call Employee's __init__() to initialize e_id and hire_year.
    • Assigns lang_xp with list parameter lang_xp.

    print_info()

    • Uses super() to print e_id and hire_year.
    • Prints "Language(s):" followed by lang_xp.
    Interactive Code
    class Employee():
        count = 0    
        def __init__(self):
            Employee.count += 1
            self.e_id = Employee.count
            self.hire_year = 2023
    
        def print_info(self):
            print("Employee", self.e_id, "was hired in", self.hire_year)
    
    # Define Developer class
    
    python_dev = Developer()
    python_dev.print_info()
     
    Answer

    class Employee():
    count = 0
    def __init__(self):
    Employee.count += 1
    self.e_id = Employee.count
    self.hire_year = 2023

    def print_info(self):
    print("Employee", self.e_id, "was hired in", self.hire_year)

    class Developer(Employee):
    def __init__(self, lang_xp):
    super().__init__()
    self.lang_xp = lang_xp

    def print_info(self):
    super().print_info()
    print("Language(s):", self.lang_xp)

    python_dev = Developer(["Python"])
    python_dev.print_info()


    This page titled 13.3: Methods 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.