Follow Techotopia on Twitter

On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
System/Network Admin
Programming
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Databases
Mail Systems
openSolaris
Eclipse Documentation
Techotopia.com
Virtuatopia.com

How To Guides
Virtualization
General System Admin
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Windows
Problem Solutions

  




 

 

Chapter 21. Classes

Object-oriented programming permits us to organize our programs around the interactions of objects. A class provides the definition of the structure and behavior of the objects; each object is an instance of a class. A typical program is a number of class definitions and a final main function. The main function creates the initial objects that will perform the job of the program.

This chapter presents the basic techniques of defining classes. In the section called “Semantics” we define the semantics of objects and the classes which define their attributes (instance variables) and behaviors. In the section called “Class Definition: the class Statement” we show the syntax for creating class definitions; we cover the use of objects in the section called “Creating and Using Objects”. Python has some system-defined names that classes can exploit to make them behave like built-in Python classes, a few of these are introduced in the section called “Special Method Names”. We provide some examples in the section called “Some Examples”. Perhaps the most important part of working with objects is how they collaborate to do useful work; we introduce this in the section called “Object Collaboration”.

Semantics

Object-oriented programming focuses software design and implementation around the definitions of and interactions between individual objects. An object is said to encapsulate a state of being and a set of behaviors; data and processing. Each instance of a class has individual copies of the attributes which are tightly coupled with the class-wide operations. We can understand objects by looking at four features, adapted from [Rumbaugh91].

  • Identity. Each object is unique and is distinguishable from all other objects. In the real world, two identical coffee cups occupy different locations on our desk. In the world of a computer's memory, objects could be identified by their address, which would make them unique.

  • Classification. This is sometimes called Encapsulation . Objects with the same attributes and behavior belong to a common class. Each individual object has unique values for the attributes. We saw this when we looked at the various collection classes. Two different list objects have the same general structure, and the same behavior. Both lists respond to append, pop, and all of the other methods of a list. However, each list object has a unique sequence of values.

  • Inheritance. A class can inherit methods from a parent class, reusing common features. A superclass is more general, a subclass overrides superclass features, and is more specific. With the built-in Python classes, we've looked at the ways in which all immutable sequences are alike.

  • Polymorphism. A general operation can have variant implementation methods, depending on the class of the object. We saw this when we noted that almost every class on Python has a + operation. Between two floating-point numbers the + operation adds the numbers, between two lists, however, the + operation concatenates the lists.

Python's Implementation. A class is the Python-language definition of the features of individual objects: the names of the attributes and definitions of the operations. Generally, the attributes are the instance variables for the object. The operations can also be called methods or method functions. All Python objects are instances of some class; the attributes of the object and methods that operate on the object are specified in the class definition.

Python permits us to define our own classes of objects. Our definition will provide a number of things.

  • We provide a distinct name to the class. We define the behavior of each object by defining its method functions. The attributes of each object are called instance variables and are created when the object is created.

  • We list the superclasses from which a subclass inherits features. This is called multiple inheritance and differs from the single-inheritance approach used by languages like Java.

  • We provide method functions which define the operations for the class.

  • We can define attributes as part of the class definition. Generally, however, our attributes are simply instance variables, which are created dynamically as the methods of the class are evaluated. Most commonly, we provide an initialization method function (named __init__) which creates our instance variables.

  • Python provides a simple version of unique identify. If necessary, we can override this definition.

Note that our instance variables are not a formal part of the class definition. This is because Python is a dynamic language; Python doesn't rely on static declarations of instance variables the way C++ or Java do.

Another consequence of Python's dynamic nature is that polymorphism is based on simple matching of method names. This is distinct from languages like Java or C++ where polymorphism depends on inheritance. Python's approach is sometimes called “duck typing”: if it quacks like a duck and walks like a duck it is a duck. If several objects have the common method names, they are effectively polymorphic with respect to those methods.

Interface and Attributes. The best programming practice is to treat each object as if the internal implementation details where completely opaque. All other objects within an application should use only the interface methods and attributes for interacting with an object. Some languages (like C++ or Java) have a formal distinction between interface and implementation. Python has a limited mechanism for making a distinction between the defined interface and the private implementation of a class.

Python uses a few simple techniques for separating interface from implementation. We can use a leading _ on an instance variable or method function name to make it more-or-less private to the class. Further, you can use properties or descriptors to create more sophisticated protocols for accessing instance variables. We'll wait until Chapter 25, Properties and Descriptors to cover these more advanced techniques.

Technically, a class definition creates a class object. This Python object defines the class by containing the definitions of the various functions. Additionally, a class object can also own class-level variables; these are, in effect, attributes which are shared by each individual object of that class.

An Object's Lifecycle. Each instance of every class has a lifecycle. The following is typical of most objects.

  1. Definition. The class definition is read by the Python interpreter or it is built-in to the language. Our class definitions are created by the class statement. Examples of built-in classes include files, strings, sequences and mappings.

  2. Construction. An instance of the class is constructed: Python allocates the namespace for the object's instance variables and associating the object with the class definition. The __init__ method is executed to initialize any attributes of the newly created instance.

  3. Access and Manipulation. The instance's methods are called (similar to function calls we covered in Chapter 9, Functions ), by client objects, functions or the main script. There is a considerable amount of collaboration among objects in most programs. Methods that report on the state of the object are sometimes calles accessors; methods that change the state of the object are sometimes called manipulators.

  4. Garbage Collection. Eventually, there are no more references to this instance. Typically, the variable with an object reference was part of the body of a function which finished, and the variables no longer exist. Python detects this, and removes the object from memory, freeing up the storage for subsequent reuse. This freeing of memory is termed garbage collection, and happens automatically. See Garbage Collection for more information.


 
 
  Published under the terms of the Open Publication License Design by Interspire