Historical Perspective Object-oriented programming was a major conceptual change in the 80s and 90s. Simula, Algol, Smalltalk were early O-O languages C++ was born from the language ‘C’. Objective-C was as well (and is now used for IPhone programming). Java was born Grouping Data Our brains can only handle 7 +- 2 things at a time. So we must create abstractions and think hierarchically. Function allow us to create an abstraction for a sequence of operations.
We also need to abstract groupings of data. We call such groupings ‘complex data types’ or ‘classes’.
Consider a social network site. What data might be recorded for each person in the system? What data might be stored for a Google search result? For a pixel?
For the Mastermind program, the partialMatches and exactMatches were data that could have been grouped together. We could have defined a class 'Feedback'.
Grouping Data in Python: Classes
How would you represent a 'Person' in Python? Lists don’t really help define a 'person' it consists of related but heterogeneous data. You really want to name each part, e.g., person.lastName, person.firstName, etc.
The class construct allows a programmer to create data abstractions. Python uses similar syntax to a function def for a class definition. Inside the class definition you can provide functions that work on the data of the class. One special such function is a constructor and its always named, __init__ (two underscores, 'init' and two more underscores). A constructor initializes the fields (components) of a class instance. It is indented within the class definition: class Person: # class definition def __init__(self): self.name="unknown" self.age=0 Once you define a class, you can create instances of it. We call these instances objects. You create them with an object creation statement, then set the fields of the object using dot (.) notation. # main p1 = Person() # this creates a Person object with name="unknown" and age=0 p2 = Person() # this creates a Person object with name="unknown" and age=0 print p1.age # prints 0 p1.age=34 # change the age of the object named p1 p1.name="Joe Williams" # change the name of the object named p1 p2.name="William Jones" # change the name of the object named p2 p2.age=22 # change the age of the object named p2 Formally, object creation statements are of the form: <object name> = <nameOfClass>()
Field assignment statements use "." to choose the field to modify or access: <objectName>.<fieldName> In the code above, Person is a class. p1 and p2 are instances of the class Person. p1 and p2 are objects of type Person. The terms 'instance' and 'object' are synonymous. name and age are fields of the class Person. Fields are also called data members. A class can also have other functions besides __init__ defined within it (we’ll revisit this later). Instructor Demo
Write a class Feedback and show how it could be used in the Mastermind program.
In-Class Assignment
1. Write a class 'Coordinate' with two fields, x and y. Provide an __init__ method which initializes x and y to zero (create the __init__ function similar to the Person class above). 2. Write a function 'distance' which accepts two coordinates as parameters and returns the distance between them. This function should be defined after the class definition (non-object-oriented) and should have a header that looks like:
# distance returns the distance from coordinate1 to coordinate2 def distance(coordinate1,coordinate2): The formula for distance is: The distance between ( x1, y1) and ( x2, y2) is given by
 You may use Python's Math Module and in particular: ‘sqrt’, and ‘pow’. 3. Write a main program to test your class and function. The main program should create two coordinates in a manner similar to how 'joe' and 'bill' were created above. It should then call the function distance, sending the two coordinate objects as parameters. Finally, it should print the coordinates and the distance between them.
Object-Oriented FunctionsIn the discussion above, we discussed programmer-defined types and used Python classes to represent them. We didn't really write an object-oriented function except for __init__ (the constructor). In the world of object-oriented programming, a class is really two things: data fields + functions that work on that data In other words, we want to organize our program by grouping each data type along with the specific functions that access and manipulate that data. For class Coordinate, we should make the function distance subordinate to the class as it works on a coordinate. class Coordinate: # note indentation... def distance(self,point2): # note the indentation # code for distance
The first formal parameter in an object-oriented function is, by convention, called self. It is the 'subject' of the function, the key piece of data. When functions are defined subordinate to a class, we call them using the form:
<object>.<function> (params) For example, point1 = Coordinate() point1.x=4 point1.y=7 point2= Coordinate() point2.x=10 point2.y=10 dist = point1.distance(point2) The last line is an object-oriented function call. point1 is the object of the call. It is mapped to the first formal parameter self. point2 is just a regular parameter and maps to the second formal parameter, also named point2.
Effectively, an object-oriented call:
dist = point1.distance(point2)
is just syntactic sugaring for:
dist1 = distance(point1,point2)
But you must call it in the object-oriented way if the function is defined subordinate to the class.
In-Class Worksheet1. Copy your coordinate program into another file, coordinate2.py. 2. Rewrite the code so that distance is a function inside the Coordinate class. Rewrite the main so that distance is called in an object-oriented manner. 3. Write a class Person with fields name and friend_list, and functions add_friend, list_friends, and get_friend_of_friends. Here are the headers for these functions:
# add_friend adds the Person friend to self's list of friends def add_friend(self,friend):
#list_friends prints the name of all self's friends def list_friends(self):
# get_friends_of_friends returns a list of Person objects who are friends of self's friends but not self's friends. def get_friends_of_friends(self):
Write a main program that creates some Person objects, adds some friends to each person, and then prints out the friends of friends correctly.
|
|