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}\)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.
Suppose a programmer inherits the ContractTax class from class Tax and wants to override Tax's calc_tax(). What should the programmer do?
- Define another
calc_tax()method inTax. - Define a
calc_tax()method inContractTax. - Define a function that takes a
ContractTaxinstance.
- Answer
-
b. Overriding involves defining a subclass method that has the same name as the superclass method.
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()
ContractTaxDEmust inherit fromTax, notContractTax.ContractTaxDE'sdefinition ofcalc_tax()is missing a parameter.ContractTaxDEcan't overridecalc_tax()sinceContractTaxalready has.
- Answer
-
b. The self parameter is missing from the overridden method's definition.
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()
- An overridden method cannot return a value.
Taxdoesn't specifycalc_tax()can be overridden.ContractTaxisn't inherited fromTax.
- 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__().
Consider the following program.
|
1
|
class Polygon:
def __init__(self, num_sides=3):
self.num_sides = num_sides
class Rectangle(Polygon):
def __init__(self, ln=1, wd=1):
super().__init__(4)
self.length = ln
self.width = wd
class Square(Rectangle):
def __init__(self, side=1):
super().__init__(side, side)
self.side = side
sq_1 = Square(5)
print(sq_1.num_sides)
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?
- 2
- 6
- 14
- Answer
-
b.
Square's superclass isRectangle.Rectangle's__init__()is called on line 6.
The next line executes. Which line does control flow move to next?
- 2
- 6
- 14
- Answer
-
a.
super().__init__(4)calls the__init__()ofRectangle's superclass,Polygon. Control moves to line 3, andnum_sidesis initialized with4.
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?
- 12
- 14
- 17
- Answer
-
b. The instance attribute side is initialized with
5.
Square's __init__() returns and control flow moves to line 17. What is the output?
345
- Answer
-
b.
Rectangle's__init__()always callsPolygon's__init__()withnum_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.
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.
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.
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
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()
Polygon typeRectangle typeSquare type
- Answer
-
c. Polymorphism allows
print_type()to be overridden in subclasses ofPolygon.
Which is an example of polymorphism for the multiplication operator?
-
x = 3 * 4 y = 3 * "la" -
x = 3 * 4 y = str(x) -
x = 3 * 4 y = x * x
- Answer
-
a. The * operator can be used with integer operands as well as strings and other types.
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
- 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()
Given the Employee class, create a Developer class inherited from Employee with methods __init__() and print_info() such that:
__init__()
- Uses
super()to callEmployee's__init__()to initializee_idandhire_year. - Assigns
lang_xpwith list parameterlang_xp.
print_info()
- Uses
super()to printe_idandhire_year. - Prints
"Language(s):"followed bylang_xp.
Interactive Code
- Answer
-
class Employee():
count = 0
def __init__(self):
Employee.count += 1
self.e_id = Employee.count
self.hire_year = 2023def 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_xpdef print_info(self):
super().print_info()
print("Language(s):", self.lang_xp)python_dev = Developer(["Python"])
python_dev.print_info()


