1 of 41

Object-Oriented Programming

Wednesday, 7/15

2 of 41

Announcements

  • Project 2 due Thursday
  • Homework 5 due Friday
  • Midterm 1 regrade requests due Sunday
    • We regraded Q4b (intersection) with a new rubric
  • Please fill out the mid-semester survey. We appreciate any feedback you can give us!
    • "Writing code live is good, but having code on lecture slides is good for reference"
    • "Labs and discussions should have trickier problems"
    • "Albert, 1v1 me in [Super Smash Bros]"
  • PSA: the full set of lecture slides are posted after lecture. Be sure to check the website after class

3 of 41

Object-Oriented Programming

  1. Review
  2. Object-Oriented Programming
    1. Classes and objects
    2. Attributes
    3. Methods
    4. Property methods
    5. Private variables (sort of)

4 of 41

Review: Functions

  • Functions: processes that describe computations
    • Order of evaluation
    • Environments
    • Control structures
    • Recursion

Functions

describing computations

5 of 41

Review: Data

  • Data: structures that store information
    • Lists, dictionaries, strings
    • Data abstraction
    • Linked lists: sequential data
    • Trees: hierarchical data

Functions

describing computations

Data

Storing information

6 of 41

Review: State

  • State: changing information over time
    • Mutabililty: can change state
      • Lists, dictionaries
    • Immutability: cannot change state
      • Tuples, strings
    • Nonlocal state in environments

Functions

describing computations

Data

Storing information

State

Changing information over time

7 of 41

Object-Oriented Programming

  • Review
  • Object-Oriented Programming
    • Classes and objects
    • Attributes
    • Methods
    • Property methods
    • Private variables (sort of)

8 of 41

Life with data abstraction

def rational(num, denom):

return [num, denom]

def numer(r):

return r[0]

def denom(r):

return r[1]

constructor

selectors

  • Abstract data type: defined in terms of behavior
  • Abstraction: supposed to treat it as a "rational" object
  • Abstraction violation: it's tempting to say "rational just returns a list!"

9 of 41

Life with data abstraction

Data abstraction

Can we do better?

Good idea:

easier to read and maintain code

Consequences:

prone to abstraction violations

10 of 41

Object-Oriented Programming

  • Review
  • Object-Oriented Programming
    • Classes and objects
    • Attributes
    • Methods
    • Property methods
    • Private variables (sort of)

11 of 41

Object-Oriented Programming

  • Object-oriented programming (OOP): a programming paradigm (technique)
  • Think of code as abstract objects
    • Objects have attributes
    • Objects can do actions
  • Different types of objects interact with each other

Name: Albert

Favorite food: burgers

walk to a destination

Attributes

Actions

pet an animal

Human

Name: Sally

Favorite food: fries

climb a tree

Attributes

Actions

pose for pictures

Squirrel

12 of 41

Object-Oriented Programming

  • Every object is an instance of a class
  • class: a type or a category of objects

Albert is a human

Sally is a squirrel

object

class

13 of 41

Object-Oriented Programming

  • Review
  • Object-Oriented Programming
    • Classes and objects
    • Attributes
    • Methods
    • Property methods
    • Private variables (sort of)

14 of 41

Object-Oriented Programming: learning by example

  • Suppose we're building a Pokemon game
  • Pokemon are creatures with different types and abilities
  • People train pokemon and battle each other

Acknowledgements: Tom Magrino and Jon Kotker developed the original Pokemon example for CS 61A, Summer 2012

15 of 41

Classes and objects

class Pokemon:

...

  • A class defines a blueprint for all objects of that type
  • The class keyword creates a class
  • Pokemon is the name of this class

"Here's what a Pokemon looks like!"

16 of 41

Classes and objects

class Pokemon:

def __init__(self, name):

...

  • The __init__ method creates an object (an instance of the class)
    • Called a constructor
  • A method is like a function (more on this later)
  • To construct a Pokemon, we give it a name (parameters)

"I want to create my own Pokemon!"

17 of 41

Classes and objects

class Pokemon:

def __init__(self, name):

self.name = name

self.level = 1

self.hp = 5 * self.level

self.damage = 2 * self.level

  • Objects can have instance attributes
  • Used to store state for a particular object

"When I create my Pokemon, I'll give it a name and it'll start at level 1"

Instance attributes

self.level might change later!

18 of 41

Classes and objects

class Pokemon:

def __init__(self, name):

self.name = name

self.level = 1

self.hp = 5 * self.level

self.damage = 2 * self.level

Pika!

>>> ashs_pikachu = Pokemon('pikachu')

>>> ashs_pikachu

<Pokemon object at …>

19 of 41

Object-Oriented Programming

  • Review
  • Object-Oriented Programming
    • Classes and objects
    • Attributes
    • Methods
    • Property methods
    • Private variables (sort of)

20 of 41

Attributes: Dot notation

>>> ashs_pikachu = Pokemon('pikachu')

>>> ashs_pikachu.name

'pikachu'

>>> ashs_pikachu.level

1

>>> ashs_pikachu.hp

5

ashs_pikachu.name

object

attribute

"The name of ashs_pikachu"

21 of 41

Attributes: Instance attributes

>>> ashs_pikachu = Pokemon('pikachu')

>>> ashs_pikachu.name

'pikachu'

>>> alberts_jigglypuff = Pokemon('jigglypuff')

>>> alberts_jigglypuff.name

'jigglypuff'

  • Different objects of same class maintain their own copies of instance attributes

Jiggly!

"The name of ashs_pikachu is different from the name of alberts_jigglypuff"

22 of 41

Attributes: self

class Pokemon:

def __init__(self, name):

self.name = name

self.level = 1

self.hp = 5 * self.level

self.damage = 2 * self.level

self is a variable that is bound to an instance of this class

From Pikachu's point of view:

"My name will be 'pikachu', and I will start at level 1"

23 of 41

Attributes: State

  • Attributes can be reassigned
  • State changes over time (mutation)

>>> ashs_pikachu = Pokemon('pikachu')

>>> ashs_pikachu.level

1

>>> ashs_pikachu.level += 9000

>>> ashs_pikachu.level

9001

"ashs_pikachu's leveled up!"

Same expression, different values!

24 of 41

Attributes: State

  • Attributes can be dynamically assigned
    • Not just when object is created

>>> ashs_pikachu = Pokemon('pikachu')

>>> ashs_pikachu.status = 'confused'

>>> ashs_pikachu.status

'confused'

"ashs_pikachu's is confused!"

Creates new instance attribute

25 of 41

Attributes: Class attributes

class Pokemon:

population = 0

def __init__(self, name):

self.name = name

self.level = 1

self.hp = 5 * self.level

self.damage = 2 * self.level

Pokemon.population += 1

>>> Pokemon.population

0

>>> ashs_pikachu = Pokemon('pikachu')

>>> Pokemon.population

1

>>> alberts_jigglypuff = Pokemon('jigglypuff')

>>> Pokemon.population

2

Class attribute: shared by all objects of the same class

26 of 41

Attributes: Attribute lookup

>>> ashs_pikachu = Pokemon('pikachu')

>>> Pokemon.population

1

>>> ashs_pikachu.population

1

Pokemon

population: 0

ashs_pikachu

name: 'pikachu'

level: 1

hp: 5

damage: 2

Pokemon

population: 1

27 of 41

Attributes: Attribute lookup

>>> ashs_pikachu = Pokemon('pikachu')

>>> Pokemon.population += 150

>>> ashs_pikachu.population

151

ashs_pikachu

name: 'pikachu'

level: 1

hp: 5

damage: 2

Pokemon

population: 1

Pokemon

population: 151

28 of 41

Attributes: Attribute lookup

>>> ashs_pikachu = Pokemon('pikachu')

>>> Pokemon.population += 150

ashs_pikachu

name: 'pikachu'

level: 1

hp: 5

damage: 2

>>> ashs_pikachu.population -= 126

>>> ashs_pikachu.population

25

>>> Pokemon.population

151

ashs_pikachu

name: 'pikachu'

level: 1

hp: 5

damage: 2

population: 25

Pokemon

population: 151

ashs_pikachu.population = ashs_pikachu.population - 126

Evaluated first: 151

Assigned to 25

29 of 41

Object identity and type checking

>>> ashs_pikachu = Pokemon('pikachu')

>>> alberts_jigglypuff = Pokemon('jigglypuff')

>>> ashs_pikachu is alberts_jigglypuff

False

>>> roberts_pikachu = ashs_pikachu

>>> ashs_pikahu is roberts_pikachu

True

>>> roberts_pikachu = Pokemon('pikachu')

>>> ashs_pikachu is roberts_pikachu

False

>>> isinstance(ashs_pikachu, Pokemon)

True

>>> type(ashs_pikachu)

<class 'Pokemon'>

(demo)

30 of 41

Object-Oriented Programming

  • Review
  • Object-Oriented Programming
    • Classes and objects
    • Attributes
    • Methods
    • Property methods
    • Private variables (sort of)

31 of 41

Methods: Your turn!

class Pokemon:

def __init__(self, name):

self.name = name

self.level = 1

self.hp = 5 * self.level

self.damage = 2 * self.level

def talk(self):

print(self.name + '!')

  • Method: a function that is bound to an object
  • Usually describes an action that the object can do
  • self refers to the object that the method is bound to

"When a Pokemon talks, it prints its name excitedly!"

self is just a variable. We can technically call it anything. It is called self by convention

32 of 41

Methods: Usage

class Pokemon:

...

def talk(self):

print(self.name + '!')

>>> ashs_pikachu = Pokemon('pikachu')

>>> ashs_pikachu.talk()

pikachu!

>>> ashs_pikachu.talk(ashs_pikachu)

TypeError

33 of 41

Methods: Methods vs. Functions

class Pokemon:

...

def talk(self):

print(self.name + '!')

>>> ashs_pikachu = Pokemon('pikachu')

>>> ashs_pikachu.talk()

pikachu!

>>> Pokemon.talk(ashs_pikachu)

pikachu!

Method call: bound to an object

Function call: not bound

(demo)

Python distinguishes between

  • functions (we've been writing these for past few weeks)
  • methods (bound to objects)

34 of 41

Methods: Your turn!

class Pokemon:

...

def decrease_hp(self, amount):

"*** YOUR CODE HERE ***"

def attack(self, other):

"*** YOUR CODE HERE ***"

  • Implement decrease_hp:
    • decreases hp by amount
    • hp cannot go below 0
  • Implement attack:
    • prints "<name> attacks <other.name>"
    • decreases other Pokemon's hp by self.damage

35 of 41

Methods

class Pokemon:

...

def decrease_hp(self, amount):

self.hp -= amount

if self.hp < 0:

self.hp = 0

def attack(self, other):

print(self.name,

'attacks',

other.name)

other.decrease_hp(self.damage)

  • Implement decrease_hp:
    • decreases hp by amount
    • hp cannot go below 0
  • Implement attack:
    • prints "<name> attacks <other.name>"
    • decreases other Pokemon's hp by self.damage

36 of 41

Object-Oriented Programming

  • Review
  • Object-Oriented Programming
    • Classes and objects
    • Attributes
    • Methods
    • Property methods
    • Private variables (sort of)

37 of 41

Property methods

class Pokemon:

def __init__(self, name):

self.name = name

self.level = 1

self.hp = 5 * self.level

self.damage = 2 * self.level

def level_up(self):

self.level += 1

self.hp = 5 * self.level

self.damage = 2 * self.level

>>> ashs_pikachu.level_up()

>>> ashs_pikachu.level

2

>>> ashs_pikachu.hp

10

>>> ashs_pikachu.level = 5

>>> ashs_pikachu.hp

10

Have to duplicate code for assigning hp and damage

38 of 41

Property methods

class Pokemon:

def __init__(self, name):

self.name = name

self.level = 1

def level_up(self):

self.level += 1

@property

def hp(self):

return 5 * self.level

@property

def damage(self):

return 2 * self.level

>>> ashs_pikachu.level_up()

>>> ashs_pikachu.level

2

>>> ashs_pikachu.hp

10

>>> ashs_pikachu.level = 5

>>> ashs_pikachu.hp

25

Property method:

technically a method, but acts like an attribute

No parentheses!

39 of 41

Property methods

>>> ashs_pikachu.level_up()

>>> ashs_pikachu.level

2

>>> ashs_pikachu.hp = 9001

AttributeError

>>> ashs_pikachu.level_up()

>>> ashs_pikachu.level

2

>>> ashs_pikachu.hp = 9001

>>> ashs_pikachu.hp

9001

Can't assign to a property method

Instance attribute

Property method

40 of 41

Object-Oriented Programming

  • Review
  • Object-Oriented Programming
    • Classes and objects
    • Attributes
    • Methods
    • Property methods
    • Private variables (sort of)

41 of 41

Private variables (sort of)

class Pokemon:

def __init__(self, name):

self.name = name

self.level = 1

self.__secret = 42

def reveal_secret(self):

return self.__secret

  • Some programming languages support private attributes
    • Private attributes cannot be accessed outside of the class
  • Python doesn't support this directly
    • "private" attributes start with double underscores
    • Python name-mangles the attribute (changes the name)
    • Can still be accessed

>>> ashs_pikachu.__secret

AttributeError

>>> ashs_pikachu._Pokemon__secret

42

>>> ashs_pikachu.reveal_secret()

42