#set document(title: "13.3 Methods", author: "OpenStax / XYZ Homework") #set page(width: 8.5in, height: auto, margin: 1in) #import "@preview/cetz:0.5.2" #set text(font: ("STIX Two Text", "Libertinus Serif", "New Computer Modern"), size: 10.5pt, lang: "en") #show math.equation: set text(font: ("STIX Two Math", "New Computer Modern Math")) #set par(justify: true, leading: 0.62em, spacing: 0.9em) #set enum(spacing: 1.1em) // room between list items so tall inline fractions don't collide #set list(spacing: 1.1em) #set table(stroke: 0.5pt + rgb("#c7ccd3")) #let BLUE = rgb("#183B6F") // brand navy — section bars + example/solution labels (white on navy 11.09:1) #let ORANGE = rgb("#A94509") // brand primary-700 — AA-safe deep orange for TEXT (5.93:1 on white; raw brand #F37021 is 2.94:1 and must never carry text) #let RED = rgb("#DC2626") // brand error-600 #let GREEN = rgb("#059669") // brand success-600 (decoration only; small green text uses green-text #007942) #show heading.where(level: 1): it => block(width: 100%, above: 0pt, below: 16pt, fill: gradient.linear(BLUE, rgb("#2C5AA0")), inset: (x: 14pt, y: 12pt), radius: 3pt, text(fill: white, weight: "bold", size: 19pt, it.body)) #show heading.where(level: 2): it => block(width: 100%, above: 18pt, below: 10pt, fill: BLUE, inset: (x: 10pt, y: 6pt), radius: 2pt, text(fill: white, weight: "bold", size: 12pt, it.body)) #show heading.where(level: 3): it => text(fill: ORANGE, weight: "bold", size: 12.5pt, it.body) #show heading.where(level: 4): it => text(fill: BLUE, weight: "bold", size: 10.5pt, it.body) #let examplebox(label, title, body) = block(width: 100%, breakable: true, fill: rgb("#EFF1F5"), stroke: 0.5pt + rgb("#CFDDF0"), radius: 4pt, inset: 10pt, above: 12pt, below: 12pt)[ #block(below: 6pt)[#box(fill: BLUE, inset: (x: 6pt, y: 2pt), radius: 2pt, text(fill: white, weight: "bold", size: 8.5pt, label)) #h(0.4em) #strong[#title]] #body] // rail = decorative left rule (raw brand token); labelcolor = AA-safe label text shade #let notebox(label, rail, labelcolor, tint, body) = block(width: 100%, breakable: true, fill: tint, stroke: (left: 3pt + rail), inset: (left: 10pt, rest: 8pt), radius: (right: 4pt), above: 11pt, below: 11pt)[ #text(fill: labelcolor, weight: "bold", size: 7.5pt, tracking: 0.5pt)[#upper(label)] #linebreak() #body] #let solutionbox(body) = block(above: 4pt, below: 8pt)[ #text(fill: BLUE, weight: "bold", size: 8.5pt)[Solution] #linebreak() #body] #let figph(msg) = block(width: 100%, height: 60pt, fill: rgb("#f6f7f9"), stroke: (paint: rgb("#c7ccd3"), dash: "dashed"), radius: 4pt, inset: 10pt)[ #align(center + horizon, text(fill: rgb("#889"), style: "italic", size: 9pt, msg))] // Standardize inlined figure sizes: measure the natural CeTZ canvas, then scale to a // consistent envelope (aspect-aware; see build_typst.py FIG_* constants). Unlike the // print preamble, dimensions are FLOORED: in an editor a user can trim a figure to a // degenerate 1-D shape (a bare line), and w/h or tw/w would then divide by zero. #let _STD_W = 3.5 #let _WIDE_W = 5.6 #let _MAX_H = 3.4 #let _ASPECT_WIDE = 2.2 #let _UPSCALE_MAX = 1.15 #let stdfig(body) = context { let m = measure(body) let w = calc.max(m.width / 1in, 0.01) let h = calc.max(m.height / 1in, 0.01) let tw = if w / h > _ASPECT_WIDE { _WIDE_W } else { _STD_W } let s = calc.min(tw / w, _MAX_H / h, _UPSCALE_MAX) align(center, box(scale(x: s * 100%, y: s * 100%, reflow: true, body))) } #show figure: set block(breakable: false) #set figure(gap: 8pt) #show figure.caption: set text(size: 8.5pt, fill: rgb("#555")) == 13.3#h(0.6em)Methods === 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 #strong[override] a superclass method by defining a method with the same name as the superclass method. #notebox("Note", rgb("#8a94a6"), rgb("#556666"), rgb("#f7f8fa"))[ #emph[Overriding a superclass method] #link("https://www.openstax.org/r/overriding-superclass")[Overriding a superclass method; ch 13, video 5] ] #notebox("Note", rgb("#8a94a6"), rgb("#556666"), rgb("#f7f8fa"))[ #emph[Overriding methods] ] === 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\_\_(). #notebox("Note", rgb("#8a94a6"), rgb("#556666"), rgb("#f7f8fa"))[ #emph[Using super() to call the superclass \_\_init\_\_() method] #link("https://www.openstax.org/r/using-super")[Using super() to call the superclass \_init\_() method; ch 13, video 6] ] #notebox("Note", rgb("#8a94a6"), rgb("#556666"), rgb("#f7f8fa"))[ #emph[Using super()] Consider the following program. 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) ] === Polymorphism #strong[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. #examplebox("Example 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. #examplebox("Example 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. #examplebox("Example 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 ] #notebox("Note", rgb("#8a94a6"), rgb("#556666"), rgb("#f7f8fa"))[ #emph[Polymorphism in practice] ] #notebox("Note", rgb("#8a94a6"), rgb("#556666"), rgb("#f7f8fa"))[ #emph[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 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() ] #notebox("Note", rgb("#8a94a6"), rgb("#556666"), rgb("#f7f8fa"))[ #emph[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. 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() ]