Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
5 views

teach_cs_toronto_edu_csc148h_notes_inheritance_inheritance_design_html

CSC148 Notes

Uploaded by

racayow849
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views

teach_cs_toronto_edu_csc148h_notes_inheritance_inheritance_design_html

CSC148 Notes

Uploaded by

racayow849
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 1

CSC148 Course Notes 3.

8 Inheritance: Thoughts on Design


CSC148 Course Notes Now that you understand the mechanics of inheritance, let’s go back and make some final comments.

1. Recapping and Extending Some


Key Prerequisite Material Four things we can do with an inherited method
1.1 The Python Memory Model:
When a subclass inherits a method from its superclass, there are four things we can choose to do in the subclass.
Introduction

1.2 The Python Memory Model:


Functions and Parameters
1. Simply inherit an implemented method
1.3 The Function Design Recipe
If a method has been implemented in the superclass and its behaviour is appropriate for the subclass, then we can simply use
1.4 Preconditions
this behaviour by choosing not to override the method. For example, HourlyEmployee does not define a pay method, so it
1.5 Python Type Annotations
simply inherits the pay method from Employee . Any time we call pay on an instance of HourlyEmployee , the
Employee.pay method is called.
2. Testing Your Code

2.1 Testing Your Work Of course, we should never do this when the method is abstract, because a subclass must override every abstract method to

2.2 Choosing Test Cases implement it properly.

2.3 Code Coverage

2.4 Introduction to Property-Based 2. Override an abstract method to implement it


Testing
When a method has not been implemented in the superclass (its body is just raise NotImplementedError ), the method
3. Object-Oriented Programming must be overridden in the subclass in order to provide an implementation.[1] For example, SalariedEmployee and
3.1 Introduction to Object-Oriented HourlyEmployee must both implement the abstract get_monthly_payment method.
Programming

3.2 Representation Invariants

3.3 The Class Design Recipe


3. Override an implemented method to replace it
3.4 More on Designing Classes If a method has been implemented in the superclass, but the subclass requires a different behaviour, the subclass can

3.5 Inheritance: Introduction and


override the method and provide a completely different implementation. This is something we haven’t yet seen, but is very
Methods simple. For example, we could override the pay method in SalariedEmployee :

3.6 Inheritance: Attributes and


Initializers class SalariedEmployee(Employee):
def get_monthly_payment(self) -> float:
3.7 Inheritance: Tracing Initialization # Assuming an annual salary of 60,000
return round(60000 / 12, 2)
3.8 Inheritance: Thoughts on
Design def pay(self, pay_date: date) -> None:
print('Payment rejected! Mwahahahaha.')
3.9 The object Class and Python
Special Methods
>>> fred = SalariedEmployee()
4. Abstract Data Types >>> fred.pay(date(2017, 9, 30))
Payment rejected! Mwahahahaha.
4.1 Introduction to Abstract Data
Types

4.2 Stacks and Queues


4. Override an implemented method to extend it
4.3 Exceptions
Sometimes we want the behaviour that was defined in the superclass, but we want to add some other behaviour. In other
4.4 Analysing Program Running
Time words, we want to extend the inherited behaviour. We have witnessed this in the initializers for our payroll system. The
Employee initializer takes care of instance attributes that are common to all employees. Rather than repeat that code, each

5. Exceptions subclass initializer calls it as a helper and then has additional code to initialize additional instance attributes that are specific to
that subclass.
5.1 Introduction to Exceptions

5.2 General Rules for try-except We can extend any inherited method, not just an initializer. Here’s an example. Suppose at pay time we wanted to print out two
5.3 Why Not Just Return a Special messages, the original one from Employee , and also a SalariedEmployee -specific message. Since we already have a
Value? superclass method that does part of the work, we can call it as a helper method instead of repeating its code:

5.4 Additional Clauses


class SalariedEmployee(Employee):
def pay(self, pay_date: date) -> None:
6. Linked Lists
Employee.pay(self, pay_date) # Call the superclass method as a helper.
print('Payment accepted! Have a nice day. :)')
6.1 Introduction to Linked Lists

6.2 Traversing Linked Lists

6.3 Linked List Mutation >>> fred = SalariedEmployee()


>>> fred.pay(date(2017, 9, 30))
6.4 Linked Lists and Running Time An employee was paid 3200 on September 30, 2017.
Payment accepted! Have a nice day. :)

7. Recursion

7.1 Motivation: Adding Up Numbers

7.2 Nested Lists: A Recursive Data Using inheritance to define a shared public interface
Structure
Our use of inheritance allows client code to do the same thing for all types of employee. Here’s an example where we iterate
7.3 Understanding Recursive
over a list of employees and call method pay on each, without regard to what kind of Employee each one is:
Functions: Partial Tracing

7.4 Writing Recursive Functions:


employees = [
Using the Recursive Structure of the SalariedEmployee(14, 'Fred Flintstone', 5200.0),
Problem HourlyEmployee(23, 'Barney Rubble', 1.25, 50.0),
SalariedEmployee(99, 'Mr Slate', 120000.0)
7.5 Writing Recursive Functions: ]
Using a Set of Test Scenarios
for e in employees:
7.6 How Recursive Code Can Fail # At this point, we don't know what kind of employee e is.
# It doesn't matter, because they all share a common interface,
7.7 Recursion and the call stack # as defined by class Employee!
# For example, they all have a pay method.
7.8 Branching recursion e.pay(date(2018, 8, 31))

8. Trees and Binary Search Trees


In other words, the client can write code to an interface defined once in the abstract class that will work for any of its
8.1 Introduction to Trees subclasses—even ones that we haven’t thought of yet!
8.2 A Tree Implementation
This is very powerful. If we couldn’t treat all kinds of employees the same way, we would need an if block that checks what
8.3 Mutating Trees
kind of employee we have and does the specific thing that is appropriate for each kind. Much messier, especially if there are
8.4 Introduction to Binary Search more than one or two subclasses!
Trees

8.5 Binary Search Tree We say that the Employee class represents the shared public interface of classes SalariedEmployee and
Implementation and Search HourlyEmployee . The public interface of a class is the way client code interacts with the methods and attributes of the class.

8.6 Mutating Binary Search Trees It’s a “shared” public interface in the sense that it is held in common between SalariedEmployee and HourlyEmployee .

8.7 Tree Traversals


We say that class Employee is polymorphic,[2] to signify that it can take different forms: as a SalariedEmployee or an
8.8 Binary Search Trees and HourlyEmployee .
Running Time

8.9 Expression Trees

Abstract classes are useful


9. Recursive Sorting Algorithms
The Employee class is abstract, and client code should never instantiate it. Is it therefore useless? No, quite the opposite!
9.1 Recursive Sorting Algorithms
We’ve already seen that it defines a shared public interface that client code can count on, and as a result, supports
9.2 Efficiency of Recursive Sorting
polymorphism. Furthermore, polymorphic client code will continue to work even if new subclasses are written in the future!
Algorithms

Our abstract Employee class is useful in a second way. If and when someone does decide to write another subclass of
Employee , for instance for employees who are paid a commission, the programmer knows that the abstract method
get_monthly_payment must be implemented. In other words, they must support the shared public interface that the client
code counts on. We can think of this as providing helpful guidance for the programmer writing the new subclass.

When to use inheritance


We’ve seen some benefits of inheritance. However, inheritance isn’t perfect for every situation. Don’t forget the other kind of
relationship between classes that we’ve seen: composition. For example, to represent people who are car owners, a Person
object might have an attribute car which stores a reference to a Car object. We wouldn’t use inheritance to represent the
relationship between Person and Car !

Composition is commonly thought of as a “has a” relationship. For example, a person “has a” car. Inheritance is thought of as
an “is a” relationship. For example, a salaried employee “is an” employee. Of course, the “has a” vs. “is a” categorization is
rather simplistic, and not every real-world problem is so clearly defined.

When we use inheritance, any change in a superclass affects all of its subclasses, which can lead to unintended effects. To
avoid this complexity, in this course we’ll stick to using inheritance in the traditional “shared public interface” sense. Moreover,
we will often prefer that a subclass not change the public interface of a superclass at all:

not by changing the interface of any public methods (e.g., adding/removing parameters, or changing their types)
not by adding new public methods or attributes to a subclass (of course, adding private attributes or methods is
acceptable)

As a general programming concept, inheritance has many other uses, and you’ll learn about some of them in CSC207,
Software Design.

[1] This is not a requirement of the Python language, but is a feature of the way we are using inheritance. In other uses of
inheritance, implementation can be deferred to a subclass of the subclass or a class further down in the inheritance chain.

[2] The roots of this word are poly, which means “many”, and morphe, which means “form”. So “polymorphic” literally means
“taking many forms”.

Previous Next
 3.7 Inheritance: Tracing Initialization 3.9 The object Class and Python Special 
Methods

By Diane Horton and David Liu


© Copyright 2022.

You might also like