0% found this document useful (0 votes)
42 views

CS1010S Tutorial 9 PDF

This document provides a summary of object-oriented programming concepts like abstraction, encapsulation, inheritance and polymorphism. It also discusses class definitions and relationships in Python, with examples of defining classes like NamedObject and subclasses like Person. Additional advice is given around using getters/setters and avoiding bugs related to string concatenation.

Uploaded by

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

CS1010S Tutorial 9 PDF

This document provides a summary of object-oriented programming concepts like abstraction, encapsulation, inheritance and polymorphism. It also discusses class definitions and relationships in Python, with examples of defining classes like NamedObject and subclasses like Person. Additional advice is given around using getters/setters and avoiding bugs related to string concatenation.

Uploaded by

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

CS1010S Tutorial 9

Object-Oriented Programming
Quick Recap

- OOP is important.
- Guaranteed one question in finals/practical each.
- If you have to code in your career, chances are you’ll run into this

- Model “stuff” as objects (Abstraction)


- Keep data/methods related to an object within a class. (Encapsulation)
- Superclassing “IS-A” relationship (Inheritance)
- E.g Pen IS-A stationary
- Polymorphism
Quick Recap
Everything in python3 is an object,
class NamedObject: subclassed (directly/indirectly) from
def __init__(self, name): Object.
self.name = name If we want to poke x, a NamedObject,
def poke(self): Do we care if x is a NamedObject or
Person?
return "No Response" x.poke()

class Person(NamedObject):
def __init__(self, name):
super.__init__(name)
def poke(self):
return f"{self.name} is annoyed"
Quick Recap: Inheritance

- Diamond Inheritance
- Left to right
- D,B,C,A
- As much as possible, avoid
this
Q1
The essential properties of a Thing are as follows :
1. The constructor should take in 1 parameter, the name of the Thing.
>>> stone = Thing ('stone')
>>> stone.owner
None
>>> stone.is_owned()
False
>>> stone.get_owner()
None
Q1
class Thing(object):
def __init__(self, name):
self.name = name
self.owner = None

def get_owner(self):
return self.owner

def is_owned(self):
return self.owner is not None
Q2
>>> stone . get_name ()

'stone '

place : Just like the owner attribute, we need to keep state of the Place object where the Thing is in.
Similarly, this attributes should be initialized to None when the Thing object is created.

>>> stone . place

None

3. get_place() : returns the place associated with the Thing.

>>> stone . get_place ()

None
Q2
class Thing(object):
def __init__(self, name):
self.name = name
self.owner = None
self.place = None ##

def get_name(self): ##
return self.name

def get_place(self): ##
return self.place
Q3
Inside hungry_games.py, you will find that get_name() is captured by the class NamedObject while
get_place() is captured by MobileObject.

class Thing ( MobileObject ):


def __init__ (self , name ):
self . name = name
self . owner = None

What is wrong with his code? Try testing with


>>> stone = Thing ('stone ')
>>> stone . get_place ()
Q3

- self.place is not defined


- Constructors of subclasses should always called super.__init__. Unless it
is a special case (almost never).
Q4: Class diagram

# NamedObject [ name | get_name ]


# |
# +-Place [ objects, neighbor_dict | add_object, del_object, get_objects,
# | get_exits, add_neighbor, get_neighbors, get_neighbor_at ]
# |
# +-MobileObject [ place | get_place ]
# |
# +- Thing [ owner, ownable | get_owner, is_owned ]
# | |
# | SDCard [ id_num | is_sdcard, copy ]
# |
# +- LivingThing [ health, threshold | get_threshold, get_health, add_health,
# | reduce_health, go_to_heaven, move_to, act ]
# |
# +- Person [ inventory | take, lose, go, say, look_around,
# | get_inventory, objects_around, get_exits, str_to_thing]
# |
# +- Troll [ | act, eat_person ]
Q4.2

Suppose we evaluate the following statements:

ice_cream = Thing (" ice_cream ")

ice_cream . owner = beng

Come up with statements whose evaluation will reveal all the properties of ice_cream and verify that its
(new) owner is indeed beng.
Q4.2

# print(ice_cream.get_owner() is beng) # verify


Q4.3
ice_cream = Thing (" ice_cream ")

ice_cream . owner = beng

beng . ice_cream = ice_cream

Is there anything wrong with the last two statements? What’s the moral of the story?
Q4.3
ice_cream = Thing (" ice_cream ")

ice_cream . owner = beng

beng . ice_cream = ice_cream

Is there anything wrong with the last two statements? What’s the moral of the story?

Nothing is wrong.
Q4.4
rum_and_raisin = NamedObject (" ice_cream ")

Are rum_and_raising and ice_cream the same object? Both are named “ice_cream”.
Q4.4
rum_and_raisin = NamedObject (" ice_cream ")

Are rum_and_raising and ice_cream the same object? Both are named “ice_cream”.

No, They are different objects, only with the same name
Q4.5
burger1 = Thing (" burger ")

burger2 = Thing (" burger ")

Are burger1 and burger2 the same object? Would burger1 == burger2 evaluate to True?

Let’s say we want to a way to compare Thing objects, and objects that have the same name and are at the
same location should evaluate to True when we compare them with ==. How would you do it? (i.e. Objects
like burger1 and burger2 should be considered equal when tested with ==.)
Q4.5

The __eq__ Method

def __eq__(self, other):


cond = isinstance(other, Thing) and \
self.get_name() == other.get_name() and \
self.get_place() == other.get_place()
return cond
Additional Advice for OOP

- Always prefer getters/setters when available


- What if you need to do something (e.g increase a counter) everytime you get/set a property
- Take note of spaces.
- E.g print(“My name is” + self.name) -> My name isE-shin
- Danger in P.E and Finals
- Look into fstrings if you want to, less prone to such careless mistakes
- print(f”My name is {self.name}”) -> My name is E-shin

You might also like