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

module4_python

Module 4 focuses on Object-Oriented Programming, covering class creation, the use of the init() method, and the self parameter. It explains encapsulation, inheritance, and the relationship between classes and instances using examples like a LibraryBook class and animal classes. The module emphasizes the importance of methods, data encapsulation, and how inheritance allows child classes to access parent class attributes and methods.

Uploaded by

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

module4_python

Module 4 focuses on Object-Oriented Programming, covering class creation, the use of the init() method, and the self parameter. It explains encapsulation, inheritance, and the relationship between classes and instances using examples like a LibraryBook class and animal classes. The module emphasizes the importance of methods, data encapsulation, and how inheritance allows child classes to access parent class attributes and methods.

Uploaded by

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

27/12/2024, 16:39 module4_python

Module 4: Object-Oriented Programming

Learning Objectives:

1. Understand the use of init () method and the self parameter. Correctly declare a class object.
2. Recognize the difference between functions and methods and the scope of methods, and make method
calls.
3. Understand how the level of inheritance affect method calls and variables.

Let's consider the library system as an example of Object-Oriented Programming.

A library has a number of books.

What should the data associated with each book be?


Are there any operations that a book should support?

So, we will build the LibraryBook class to store data about each book and support methods/operations
needed in the Library System.

Classes are blueprints or designs or templates for instances. The relationship between a class and an
instance is similar to the one between a cookie cutter and a cookie.

A single cookie cutter can make any number of cookies. The cutter defines the shape of the cookie.
The cookies are edible, but the cookie cutter is not.

References from Columbia University Professor Daniel Bauer's ENGI1006 Lectures

In [ ]: # LibraryBook is the name of the class


class LibraryBook:
"""
A library book
"""

# pass indicates that the body/suit of the class definition is empty.


pass

In [ ]: # This will create an instance of the class.


my_book = LibraryBook()
my_book

Out[ ]: <__main__.LibraryBook at 0x7fca565e5d30>

In [ ]: type(my_book)

Out[ ]: __main__.LibraryBook

https://cdn.evg.gov.br/cursos/338_EVG/htmls/modulo04_html01.html 1/9
27/12/2024, 16:39 module4_python

In [ ]: # Another way to check the type of some object


isinstance(my_book, LibraryBook)

Out[ ]: True

Why use classes and when??

Objects simplify problems by providing an abstraction over certain data types and their functionality.

Instead of thinking of the problem in terms of individual strings, integers, etc. we can now
think in terms of LibraryBooks (or other objects).

Encapsulation

Data and functionality is bundled in objects.


The methods provide an interface to the object. Ideally the individual data are only written and read
through methods.
This means that details about how the functionality is implemented is hidden from the programmer. For
example, we don't know how the append method on lists is implemented.
This idea allow classes to be shared (in libraries) and used by others (or re-used by you) without having
to read through the source code for the class.

4.1: init, Self Parameter

Data fields - Each instance owns its own data (the class can define what names the data fields have).

The init(self, ...) method is automatically called by Python when a new instance is created. This method is
called the class constructor; it initialize the data values in the class.

In [ ]: """
A library book.
"""
class LibraryBook (object):

"""
The self parameter is REQUIRED within the class,
because it tells the program to retrieve/act on the instance object
that called it.
"""
def __init__(self, title, author, pub_year, call_no):
self.title = title
self.author = author
self.year = pub_year
self.call_number = call_no
self.checked_out = False

https://cdn.evg.gov.br/cursos/338_EVG/htmls/modulo04_html01.html 2/9
27/12/2024, 16:39 module4_python

In [ ]: """
Since we have already created my_book as a LibraryBook object,
we could now manually add the title, author,... information associated with
the book.
"""

my_book.title = "Harry Potter and the Philosopher's Stone"


my_book.author = ('Rowling', 'J.K.')
my_book.year = 1998
my_book.call_number = "PZ7.R79835"

In [ ]: # Retrieve a specific data field of an instance by calling instance name an


d the field name
my_book.author

Out[ ]: ('Rowling', 'J.K.')

In [ ]: """
Or we could pass all the information into the __init__ to set up the fields
when creating the new instance.
"""

new_book = LibraryBook("Harry Potter and the Sorcerer's Stone",


("Rowling","J.K."), 1998, "PZ7.R79835")

new_book.author

Out[ ]: ('Rowling', 'J.K.')

4.2: Methods

Methods contain the functionality of the object.

These are defined in the class.

https://cdn.evg.gov.br/cursos/338_EVG/htmls/modulo04_html01.html 3/9
27/12/2024, 16:39 module4_python

4.2.1: Writing a Method

In [ ]: class LibraryBook(object):
"""
A library book.
"""

def __init__(self, title, author, pub_year, call_no):


self.title = title
self.author = author
self.year = pub_year
self.call_number = call_no

"""
Methods for LibraryBook
"""

# Returns the title and author information of the book as a string


def title_and_author(self):
return "{} {}: {}".format(self.author[1], self.author[0], self.titl
e)

# Prints all information associated with a book in this format


def __str__(self): #make sure that __str__ returns a string!
return "{} {} ({}): {}".format(self.author[1], self.author[0], sel
f.year, self.title)

# Returns a string representation of the book with it' title and call_n
umber
def __repr__(self):
return "<Book: {} ({})>".format(self.title, self.call_number)

In [ ]: # Simply calling the instance itself is triggering __repr__()


new_book

Out[ ]: <__main__.LibraryBook at 0x7fca565db278>

In [ ]: # print is triggering the __string__()


print(new_book)

<__main__.LibraryBook object at 0x7fca565db278>

In [ ]: new_book = LibraryBook("Harry Potter and the Sorcerer's Stone",


("Rowling","J.K."), 1998, "PZ7.R79835")

new_book.title_and_author()

Out[ ]: "J.K. Rowling: Harry Potter and the Sorcerer's Stone"

https://cdn.evg.gov.br/cursos/338_EVG/htmls/modulo04_html01.html 4/9
27/12/2024, 16:39 module4_python

4.2.2: Internal/External Method Calls

The ONLY differce is:

Externally/outside the class, you would simply call instanceName.method(), like


new_book.title_and_author()
Internally/within the class, you would use the self to points to that specific instance of the class, like
self.title_and_author()

4.3: Inheritance

Example of instance-of relationship.

nemo is an instance of ClownFish.

In [ ]: class ClownFish(object):
pass

nemo = ClownFish()

In [ ]: type(nemo)

Out[ ]: __main__.ClownFish

In [ ]: isinstance(nemo, ClownFish)

Out[ ]: True

But ClownFish is also a fish, a vertebrate, and an animal, and each could a separate class.

In this case, we need to have relationships between class.

The ClownFish class could have the parent class Fish,


which could have a parent class Vertebrate,
which could have a parent class Animal...

This relationship is called the is-a relationship. It holds between a child class and its parent class. Every class
in Python has at least one parent class.

(Note that the is-a relationship is transitive, so every ClownFish is also an Animal.)

There is a top-most class in Python called object. So far, when we defined classes, we always made object
the direct parent of the class.

https://cdn.evg.gov.br/cursos/338_EVG/htmls/modulo04_html01.html 5/9
27/12/2024, 16:39 module4_python

In [ ]: class Animal(object):
pass

class Vertebrate(Animal):
pass

class Fish(Vertebrate):
pass

class ClownFish(Fish):
pass

class TangFish(Fish):
pass

In [ ]: nemo = ClownFish()

In [ ]: isinstance(nemo, ClownFish)

Out[ ]: True

In [ ]: isinstance(nemo, TangFish)

Out[ ]: False

In [ ]: # the is-a relationship is transitive


isinstance(nemo, Animal)

Out[ ]: True

In [ ]: # All classes have a parent class of Object.


isinstance(nemo, object)

Out[ ]: True

4.3.1: Inherited Methods

Why use inheritance?

Every class also has access to the class attributes of the parent class. In particular, methods defined on the
parent class can be called on instances of their "decendants".

In [ ]: class Fish(Animal):
def speak(self):
return "Blub"

class ClownFish(Fish):
pass

class TangFish(Fish):
pass

https://cdn.evg.gov.br/cursos/338_EVG/htmls/modulo04_html01.html 6/9
27/12/2024, 16:39 module4_python

In [ ]: dory = TangFish()

"""
TangFish is a child class of Fish, so it can access the speak() from Fish c
lass.
It will first look for the method call within its class, and if not found,
then repeat
the search for each parent level up.
"""
dory.speak()

Out[ ]: 'Blub'

In [ ]: nemo = ClownFish()

# ClownFish is a child class of Fish, so it can access the speak() from Fis
h class

nemo.speak()

Out[ ]: 'Blub'

What if we want different functionality for a child class? We can override the method (by writing a new one
with the same name).

In [ ]: class TangFish(Fish):
def speak(self):
return "Hello, I'm a TangFish instance."

In [ ]: dory = TangFish()

# this speak() is from the TangFish class


dory.speak()

Out[ ]: "Hello, I'm a TangFish instance."

In [ ]: """
On the other hand, since the ClownFish class still does NOT
define the speak(), instances of ClownFish are still using the
speak() from the parent class of Fish.
"""

nemo = ClownFish()
nemo.speak()

Out[ ]: 'Blub'

In [ ]: # What happen when we want to print the nemo instance?


print(nemo)

<__main__.ClownFish object at 0x7fca565dbf60>

When you write your own special method (like str). You are overriding the method of the same name defined
in object.

https://cdn.evg.gov.br/cursos/338_EVG/htmls/modulo04_html01.html 7/9
27/12/2024, 16:39 module4_python

In [ ]: # The print statement is not easy to understand, so we will override it.

class ClownFish(Fish):
def __init__(self, name):
self.name = name
def __str__(self):
return "A ClownFish named "+self.name

In [ ]: nemo = ClownFish('Nemo')

print(nemo)

A ClownFish named Nemo

4.3.2: Accessing Variable with Inheritance

In a is-a relationship, the child classe could access the parent class's attributes if not defined in the child
class, or override the attribute value of same attribute exists in the child class.

However, if an instance is defined at one of the parent class levels, then it could NOT access the attributes
that are defined in any of the lower child class level.

In [ ]: class Fish(Vertebrate):

# self.name is not defined in Fish class, but is defined in the ClownFi


sh class.
def __str__(self):
return "Hello, my name is {}".format(self.name)

class ClownFish(Fish):
def __init__(self, name):
self.name = name

In [ ]: nemo = ClownFish("nemo")

# The self.name attribute for the __str__() is from the ClownFish class
# but the __str__() is from the Fish class
print(nemo)

Hello, my name is nemo

https://cdn.evg.gov.br/cursos/338_EVG/htmls/modulo04_html01.html 8/9
27/12/2024, 16:39 module4_python

In [ ]: """
ERROR, because if nemo is an instance of fish class,
then it does NOT have the name attribute.
"""
nemo = Fish()
print(nemo)

--------------------------------------------------------------------------
-
AttributeError Traceback (most recent call las
t)
<ipython-input-33-3dff370cc698> in <module>()
4 """
5 nemo = Fish()
----> 6 print(nemo)

<ipython-input-31-b5476c627494> in __str__(self)
3 # self.name is not defined in Fish class, but is defined in th
e ClownFish class.
4 def __str__(self):
----> 5 return "Hello, my name is {}".format(self.name)
6
7 class ClownFish(Fish):

AttributeError: 'Fish' object has no attribute 'name'

In [ ]: class Fish(Vertebrate):
def __init__(self, name):
self.name = name

# self.name is not defined in Fish class, but is defined in the ClownFi


sh class.
def __str__(self):
return "Hello, my name is {}".format(self.name)

class ClownFish(Fish):
def __init__(self, name):
self.name = name

In [ ]: nemo = ClownFish("Nemo")

# __str__() is accessing the self.name from the child level


print(nemo)

Hello, my name is Nemo

In [ ]: nemo = Fish("clown_fish")

# __str__ ia accessing the self.name attribute from Fish class


print(nemo)

Hello, my name is clown_fish

In [ ]:

https://cdn.evg.gov.br/cursos/338_EVG/htmls/modulo04_html01.html 9/9

You might also like