CS51A - Spring 2019 - Class 23

Example code in this lecture

   person.py
   rectangle.py
   rectangle2.py

Lecture notes

  • administrative
       - midterm a week from today
       - no lab/class Friday, though there will be an assignment
       - extra mentor hours over the weekend

  • objects
       - objects have two pieces of information:
          - data
          - methods
       - for example, a list is an object
          >>> l = [1, 2, 3, 4]
          >>> l.append(5)
          >>> l
          [1, 2, 3, 4, 5]
          >>> l.reverse()
          >>> l
          [5, 4, 3, 2, 1]

  • method types
       - there are two types of methods:
          - mutator methods
             - change or mutate the object
          - accessor methods
             - do not change the object
             - ask questions about the object
       - you can look at all of the methods available for an object using help:
          >>> help(l)
          
          or

          >>> help(list) # the type of the object

  • constructors
       - every object has a special method called a constructor
       - it has the same name as the type of the object and can be called on it's own to "construct" a new object
       - Many of the methods we've actually been using already are actually constructors!
          >>> str(10)
          '10'
          >>> int("10")
          10
          >>> float(10)
          10.0

          - all of these construct a new object of that type
       - Some things (like lists and tuples) have special ways of constructing them, but they too also have constructors
          >>> list()
          []
          >>> tuple()
          ()
          >>> list( "abcde" )
          ['a', 'b', 'c', 'd', 'e']
          >>> tuple( "abcde" )
          ('a', 'b', 'c', 'd', 'e')
          >>> tuple( [1, 2, 3, 4] )
          (1, 2, 3, 4)

  • classes
       - a "class" is the blueprint describing what data and methods an object will have
       - an object is an instance of a class
          - for example, we could define a class people
             - people have attributes
             - people will have methods
             - when we define a particular person, it is an object that is an instance of the class or people
       - classes define types
          - in Python, since all things are objects, then they all represent instances of objects
          - though in other languages, you could have a type that is not defined by a class


  • defining our own classes
       - syntax:

          class name_of_class:      
             # methods in the class

       - look at Person class in person.py code
          - 5 methods
          - 2 "special" methods
             - methods that are surrounded by two underscores on each side are "special" methods
             - they are generally NOT called directly
             - __init__ defines the constructor for the method
             - __str__ defines what the object will be when it is used in a string context, e.g. printed

       - self
          - self is a variable that allows us to store data and retrieve data in an object
          - self is a reference to the current object
          - it should be the first parameter to every method in a class (not totally true, but fine for this class)
             - though you do NOT include it when you call the methods (this is a little annoying, but you'll get used to it)
             - this is also how we indicate that a function is a method
          - we can access the "data" associated with a class by using self, e.g.
             self.x = 10

             creates a new instance variable (variable associated with this object) called x and assigns it the value 10

       - look at the constructor (__init__ method) in person.py code
          - takes self and two parameters
          - all it does is SAVE these parameters into the object
             - self.name creates a new instance variable called name and stores persons_name into it

       - look at the "get_" methods in person.py code
          - these are accessor methods
          - give us information back
          - notice they only take self as a parameter and use that to give back characteristics about the object

       - look at the "change_shirt" method

  • write a class called Rectangle
       - that has a constructor that takes x1, y1, x2, y2 (and self)
       - and one method called area that returns the area of the rectangle
       
  • look at the Rectangle class in rectangle.py code
       - many different ways we could have implemented this
       - in this version, I chose to store the two points as x, y pairs, specifically 4 instance variables:
          self.x1
          self.y1
          self.x2
          self.y2
       - init
          - just saves away the input parameters into instance variables so we can use them later
             self.x1 = x1

             says take the parameter x1 and put its value into the instance variable self.x1
          - this creates 4 instance variables
       
       - area
          - uses the four instance variables to calculate the width and height of the rectangle
          - we need to use abs since we don't specify that the x,y pairs are lower left and upper right corners


  • why classes?
       - encapsulation
          - look at the Rectangle class in rectangle2.py code
             - we have the exact same set of methods (constructor and area)
             - however, we have *different* internal representation
                - we store the lower left hand corner (x,y)
                - and the width and height of the rectangle
             - notice that we can ask the exact same questions using this representation
          - anyone using the Rectangle class should NOT care which version we use
             - both have the same set of methods and the same functionality
             - this is the power of using classes, a general framework called object-oriented programming

       - modularity
          - functions create single units that we can use to build up other functions
          - in the same way, classes allow us to create functional units (in this cases a class of objects with a particular behavior)

       - avoid naming conflicts