Why Objects?

  • Provide modularity and reuse through hierarchical structures

Object oriented programming is a different way of thinking.

Programming With Objects


In [1]:
from IPython.display import Image
Image(filename='Classes_vs_Objects.png')


Out[1]:

Initial concepts

  • An object is a container of data (attributes) and code (methods)
  • A class is a template for creating objects

Reuse is provided by:

  • reusing the same class to create many objects
  • "inheriting" data and code from other classes

In [2]:
# Definiting a Car class
class Car(object):
    pass

Attributes


In [3]:
from IPython.display import Image
Image(filename='ClassAttributes.png')


Out[3]:

Attributes are data associated with an object (instance) or class. Object attributes (and methods) are specified by using "self". Instance attributes and methods are accessed using the dot "." operator.


In [4]:
class Car(object):
    
    # The following method is called when the class
    # is created or "constructed". The variables "self.x" refers
    # to the variable "x" in a created object.
    def __init__(self, color, car_type, speed):
        self.color = color
        self.car_type = car_type
        self.speed = speed

In [7]:
class Car(object):
    
    # The following method is called when the class
    # is created or "constructed". The variables "self.x" refers
    # to the variable "x" in a created object.
    def __init__(self, color, car_type, speed):
        self.color = color
        self.car_type = car_type
        self.speed = speed

In [8]:
# Creating an object for a class with arguments in the __init__ method
car = Car("Blue", "HatchBack", 100)
car.color


Out[8]:
'Blue'

In [9]:
# Creating an object for a class with arguments in the __init__ method
joe_car = Car("Blue", "Sedan", 100)
dave_car = Car("Red", "Sports", 150)
print ("Type of joe_car is %s. Type of dave_car is %s"% (type(joe_car), type(dave_car)))


Type of joe_car is <class '__main__.Car'>. Type of dave_car is <class '__main__.Car'>

In [10]:
# Accessed instance attributes
joe_car = Car("Blue", "Sedan", 100)
print ("Type of joe_car has (color, type, speed)=%s." % str((joe_car.color, joe_car.car_type, joe_car.speed)))


Type of joe_car has (color, type, speed)=('Blue', 'Sedan', 100).

EXERCISE: Change the constructor for Car to include the attribute "doors".

Instance Methods


In [11]:
from IPython.display import Image
Image(filename='InstanceMethods.png')


Out[11]:

In [12]:
#Class diagram
from IPython.display import Image
Image(filename='SingleClassDiagram.png', width=200, height=200)


Out[12]:

A class diagram provides a more compact representation of a class. There are three sections.

  • Class name
  • Attributes
  • Methods

Instance methods

  • functions associated with the objects constructed for a class
  • provide a way to transform data in objects
  • use instance attributes (references to variables beginning with "self.")

In [13]:
class Car(object):
    
    def __init__(self, color, car_type, speed):
        """
        :param str color:
        :param str car_type:
        :param int speed:
        """
        self.color = color
        self.car_type = car_type
        self.speed = speed
        
    def start(self):
        print ("%s %s started!" % (self.color, self.car_type))
        
    def stop(self):
        pass
        
    def turn(self, direction):
        """
        :parm str direction: left or right
        """
        pass

In [14]:
car = Car("Blue", "Sedan", 100)
car.start()


Blue Sedan started!

EXERCISE: Implement the stop and turn methods. Run the methods.

Inheritance

Inheritance is a common way that classes reuse data and code from other classes. A child class or derived class gets attributes and methods from its parent class.

Programmatically:

  • Specify inheritance in the class statement
  • Constructor for derived class (class that inherits) have access to the constructor of its parent.

Inheritance is represented in diagrams as an arror from the child class to its parent class.


In [15]:
from IPython.display import Image
Image(filename='SimpleClassHierarchy.png', width=400, height=400)


Out[15]:

In [16]:
# Code for inheritance
class Sedan(Car):
    # Sedan inherits from car
    
    def __init__(self, color, speed):
        """
        :param str color:
        :param int speed:
        """
        super().__init__(color, "Sedan", speed)
        
    def play_cd(self):
        print ("Playing cd in %s sedan" % self.color)

In [17]:
sedan = Sedan("Yellow", 1e6)
sedan.play_cd()


Playing cd in Yellow sedan

In [18]:
sedan.car_type


Out[18]:
'Sedan'

In [19]:
joe_car = Sedan("Blue", 100)
print ("Type of joe_car has (color, type, speed)=%s." % str((joe_car.color, joe_car.car_type, joe_car.speed)))


Type of joe_car has (color, type, speed)=('Blue', 'Sedan', 100).

Exercise: Implement SportsCar and create dave_car from SportsCar. Print attributes of dave_car.


In [20]:
from IPython.display import Image
Image(filename='ClassInheritance.png', width=400, height=400)


Out[20]:

Subclasses can have their own methods.

Exercise: Add the play_cd() to Sedan and play_bluetooth() method to SportsCar. Construct a test to run these methods.

What Else?

  • Class attributes
  • Class methods

Object Oriented Design

A design methodology must specify:

  • Components: What they do and how to build them
  • Interactions: How the components interact to implement use cases

Object oriented designed

  • Components are specified by class diagrams.
  • Interactions are specified by interaction diagrams.

Class diagram for the ATM system


In [21]:
from IPython.display import Image
Image(filename='ATMClassDiagram.png', width=400, height=400)


Out[21]:

The diamond arrow is a "has-a" relationship. For example, the Controller has-a ATMInput. This means that a Controller object has an instance variable for an ATMInput object.

Interaction Diagram for the ATM System

An interaction diagram specifies how components interact to achieve a use case.

Interactions are from one object to another object, indicating that the first object calls a method in the second object.

Rules for drawing lines in an interaction diagram:

  • The calling object must know about the called object.
  • The called object must have the method invoked by the calling object.

In [22]:
from IPython.display import Image
Image(filename='ATMAuthentication.png', width=800, height=800)


Out[22]:

Look at Objects/ATMDiagrams.pdf for a solution.

What Else in Design?

  • Other diagrams: state diagrams, package diagrams, ...
  • Object oriented design patterns

Complex Example of Class Hierarchy


In [23]:
from IPython.display import Image
Image(filename='SciSheetsCoreClasses.png', width=300, height=30)


Out[23]: