Computer Science 110
Foundations of Computing

Denison

Using Object Functions


Introduction

Consider the basic data types we have encountered thus far -- integers (int), real numbers (float), and strings (str). Each data type, by definition, can represent a set of possible values and each has a set of associated operations. Through the assignment statement and using more complex expressions, we can manipulate the values of these basic data types in our programs, and can combine the operations of addition, subtraction, multiplication, and so on with the power of built-in functions such as pow() and abs(), and round() so that we can further manipulate these values and compute results.

When considering our underlying use of computation -- to solve problems in the real world by modeling real-world concepts by our values and then designing a sequence of instructions to manipulate these values to compute a solution to our problem -- we may find these basic data types conceptually limiting. After all, concepts in the real world are often more complicated than just integers and reals and sequences of characters.

Most modern computer programs are built using much richer data types, generically called classes and objects, that programmers can use to represent more complex values. The practice of using objects for modeling real-world entities and using our computer programs to manipulate these objects through sequences of statements is called object oriented programming, and a programming language that allows programmers to design the template of an object, with its associated data and operations, and then to instantiate the template as individual values (also called objects) is called an object oriented programming language. Most real programs are, in fact, a combination of procedural programming (what we have seen so far) along with object oriented programming (which we are now introducing). So we are building on what we have learned so far, we are not supplanting it. Python is an object oriented programming language and allows object oriented programming in addition to the procedural programming we have learned thus far.

So what, in computer science and programming language terms, _is_ an object. The key idea is to extend what we know about our basic data types. In our basic data types, there is the value part of the data type -- the set of possible values an int might take on, for example, and the set of legal operations for the data type -- addition, substraction, multiplication, division, integer division, modulo, and exponentiation for integers. For our object data types, there are the same two qualities to the object data type -- the value(s) or data that make up the object, and a set of operations. Here, however, we don't have the convenience of single/double characters to denote the operation (like the +, -, *, /, //, ** for integers), so the designer of an object data type (or class) can use object functions to describe the operations allowed for the object. In the parlance of the field, these object functions are called methods.

In the remainder of this supplemental textbook section, we will use simple graphics programming to illustrate the idea of objects and, to the point of the section, how to create objects and then how to invoke the methods of the created objects.

Object Creation

Because objects are, generally, more complex than our basic data types, we need additional richness and help from the programming language to create them. For the basic data types, we could create an int or a float or a str by simply assigning an expression of the correct type to a variable, and the variable would then be associated with the desired value. When we create an object, we often also use assignment so that the created value can be associated with a variable, but the RHS of the assignment invokes a special function whose purpose is to create an object of the desired object type. The term class is used to refer to the generic object type, and the term object is used for the instance of the object with its own value.

The definition of one or more object classes are typically gathered together into a module, and we need to import the module to gain access to the needed definitions. For the examples that follow, we can do the following:

from Graphics import *

It is also possible to gain access to both the Graphics programming definitions as well as Myro robot functions by instead performing:

from Myro import *

You will generally do one of the above, but not both.

For our first example of an object creation, we will create an object associated with a Graphics Window. The creation of the object happens through a special Constructor Function, and this function yields a value whose data type is a Window object. Like other functions, this Constructor Function allows multiple arguments (three in this case), which are evaluated before the constructor is executed in the same was as the evaluation of any function invocation. So we get the following:

first_win = Window("Tom's Graphics Window", 500, 350)

Note that there is nothing special about first_win; it is simply the name of a variable chosen by the programmer. The three arguments to the Window constructor function are all simple constant literals -- one str and two ints. These could be variables or more complex expressions if desired. If the application needed more than one graphics window, this could be followed by another object creation:

second_win = Window("Another Window", 200, 250)

At this point, it may be clear that the second argument to the Window function is the desired width of the created window and the third argument is the desired height of the desired window. The units for both of these arguments is pixels -- the tiny dots of a computer screen. Although we have two objects at present in this example, there is only one class that governs generic properties of a Window, from the data maintained as the value part of the object to the set of methods available for the object.

Method Invocation

When we want to invoke the object functions, or methods, of an object, we must, as a programmer, specify the object that the operation pertains to. So if I desired an expression to retrieve the width of the first window, and I know the name of the method is getWidth() and the method has no arguments, I would invoke the function:

first_win.getWidth()

If I wanted the height of the second Window, I could similarly use an expression for a method invocation:

second_win.getHeight()

Consider the syntactic differences from what we know from before: we have prefixed a "normal" function invocation with a reference to an object value. In this case, the reference is the name of a variable that is associated with the object we wish to manipulate. This is the mechanism we use to specify the object that the operation pertains to. Notice that nothing else has changed ... I use functions/methods that yield as an expression and evaluate it in the same way as before. Such expressions can appear in assignment statements or in evaluation requests to the shell, or anywhere such an expression would normally be valid. Similarly, I use functions/methods that do not yield a value as category of statement in a sequence for Python to interpret one after another.

If Color is an object type that we can employ in graphics windows, then we can construct a particular color using a Constructor Function that takes a string argument specifying the color:

blackColor = Color("Black")

and we can invoke a method of the Window class that does not return a value as a simple statement:

first_win.setBackground(blackColor)

By knowing the semantics of expression evaluation of function invocation, I can compose those two operations:

first_win.setBackground(Color("Black"))

Say that I wish to add a red circle to my first graphics window, centered at point 150, 100 in the coordinate system of the graphics window, and with radius 50. We should first note that the pixel coordinate system used on computers places the origin point (0, 0) in the upper left corner of any window displayed on the computer. The x coordinates increase linearly to the right, and the y coordinates increase linearly down. This is different from the coordinate system we learned in algebra, in which the y coordinates increase as we move up (or North) in the two dimensional space.

I'll first give the sequence of Python statements to accomplish this, and then add some emplanation:

centerPoint = Point(150, 100)
circ = Circle(centerPoint, 50)
circ.setFill(Color('Red'))
circ.draw(first_win)

The first two statements are assignment statements, each one creating an object and assoicating a variable with the created object. The first object is of type Point, and the other object is of type Circle. A Point is created with an x and a y coordinate. The creation of a Circle requires the value of a Point for its center, along with an integer radius.

The second two statements are method invocations. They apply to the Circle object we just created, and which is referenced by variable circ. The first sets the fill color of the circle, and its argument is a red Color. The second actually draws the circle, and links together the circle with the graphics window we want to hold the circle. Up to this point, the circle was kind of abstract, and could have been drawn in any available window.

The Graphics/Myro libraries support many different objects that can be used in a graphics programming. Some of these include Rectangles, Lines, Arcs, Ellipse, Pictures, Curves, Arrows, and many others. All of the shapes have some common methods that apply regardless of the type of shape, such as setFill, while other methods are specific to the particular shape. The reader is encouraged to look at the documentation and examples at Calico Graphics and to try the examples out either as Python scripts, or in the Python Shell.

Accessing Object Variables

Since objects often aggregate together a collection of values that make up the "value" of the overall object, there are times when programmers want to retrieve and to set those constituent values. While the designer of a class may provide methods on the object to retrieve and set these individual values, sometimes object oriented programming languages (like Python) offer a simpler way of getting the same thing done.

Assuming the graphics window setup from above, try typing the following expression into the Python shell:

first_win.width
Now try typing the following assignment statement:
first_win.title = 'Foo'
First note that these are not method invocations on the first_win object like we performed earlier. We know this because we lack the parenthesis required for method/function invocation. Instead, the variable names width and title refer to some of the individual values that make up the data portion of the Window object, first_win.

We construct an expression for an object variable reference by prefixing the variable name with a reference to an object instance, followed by a '.'. With this new construct, we can then create references to object variables and to use them in expressions and in statements in the same way we use non-object references to values in our valuespace.


 All rights reserved, Thomas C. Bressoud and Denison University
For problems or questions regarding this web, contact bressoud@denison.edu.
Last updated: Thu, September 5, 2013 3:02 PM .