Unit 10: Object-Oriented Programming
We are now ready to transition into object-oriented programming, which organizes code in the form of what are referred to as classes. In Python, every variable created is an object, and, as you have already seen, each variable has access to a set of methods. This is because there exists a class definition housing the methods that a given object has access to. In this unit, you will learn how to design your own classes, create or "instantiate" objects from a given class, and write programs that apply your class designs.
Completing this unit should take you approximately 8 hours.
Upon successful completion of this unit, you will be able to:
- explain the differences between procedural, structured, and object-oriented programming;
- explain how classes, objects, and instances are used in object-oriented programming; and
- implement simple programs that use classes, objects, and instances.
10.1: Overview of Object-Oriented Programming
We have been learning, accessing, and applying methods available in Python (it would be impossible to teach Python without doing so). Although the syntax and use of these methods are inherently object-oriented, we have been using them in the context of procedural program design and in the form of structured programs. Recall that procedural programs use functions as a way of breaking a program down into a set of procedures to solve a problem. Read this page to learn why we have been arranging our programs the way we have.
It is important to understand how object-oriented programs differ from procedural programs. The main goal of object-oriented programming is to allow the problem being solved to dictate the class design. For instance, a house is organized as a function of its rooms: living room, kitchen, bedroom, and so on. Each room is organized as a function of its furniture and its use. Each room could define a new class containing attributes that define the furniture and methods that define their use. The process of breaking a problem down into a set of classes each with its own set of attributes and methods is called data abstraction. This process is in stark contrast to procedural programming. Read this page to see how these approaches differ.
10.2: Object-Oriented Programming (OOP)
Try typing these commands in Repl.it:
a=[1,2,3,4,5] print(dir(a))
After creating the list object, you should see that the dir command generates a complete list of methods available for operating on that object. Notice that some of the methods have a double underscore on both sides of the method name. For instance, the
__add__
method has a double underscore as both a prefix and a suffix, while the append command does not. Methods that have a double underscore as both a prefix and a suffix are called "dunder methods" (for double underscore) or "magic methods". Magic methods do not need to be called explicitly. As we will see in the examples ahead, magic methods run automatically in response to some action invoked by some other command. The main point is that an object is somehow able to access a suite of methods. In this unit, you will learn how and why this is so. The first step is to master some basic terminology that will link together and reinforce terms and concepts relevant to object-oriented programming such as classes, methods, attributes, objects, instances, and so on.Read this page to learn more.
We will now introduce Python class construction along with how to create object instances. The example below defines a class
Rectangle
along with various methods useful for operating on rectangles such asarea
andperimeter
. Run the following code in Repl.it:class Rectangle: def __init__(self,x,y): self.length=x self.width=y def __str__(self): return 'Length='+str(self.length)+' Width='+str(self.width) def area(self): return self.width*self.length def perimeter(self): return 2*self.width+2*self.length def rescale(self,a): self.width=a*self.width self.length=a*self.length def __del__(self): print("This object no longer exists") examp1=Rectangle(3,5) print(type(examp1)) print(examp1) print(examp1.area()) print(examp1.perimeter()) examp1.rescale(2) print(examp1) examp2=Rectangle(2,4) print(examp2) print(examp2.area()) print(examp2.perimeter()) examp1=42 del examp2
Some important observations:
- The keyword
class
alerts Python that a new class is being defined. - The class name is Rectangle and the declaration terminates with a colon (:).
- Generally, as a convention, the class name is capitalized.
- All subsequent code contained within the class definition is indented.
- Method definitions (in a manner similar to functions) commence with the def keyword and terminate with a colon (:).
,__init__
, and__del__
are Python magic methods.__str__
area
,perimeter
andrescale
are user-defined methods contained within theRectangle
class.- The self variable is the object currently being referenced (more on this in a moment).
- In Python,
self
is not a reserved keyword, but it is a very strong convention to use this variable name when referring to an object within a class definition. examp1
andexamp2
are objects instantiated from the classRectangle
- The attributes for each object are
length
andwidth
- Each object is initialized with its own set of attribute values
- The syntax of method calls such as
examp1.perimeter()
orexamp1.rescale(2)
using the dot notation should be familiar at this point in the course.
You can think of the class definition as a brand new variable type endowed with all the attributes and methods defined within the class. The code following the class definition demonstrates how it can be used.Given the class definition, it is possible to create multiple instances called "objects". Each object has access to the methods defined within the class, but retains its own attribute values. For instance, the commands
examp1=Rectangle(3,5) examp2=Rectangle(2,4)
will instantiate two objects from the class
Rectangle: examp1
andexamp2
.Each object can use the class methods to compute the area, the perimeter, or rescale using the length and width provided as the input.The
examp1
andexamp2
objects are said to be instances of the classRectangle
.At the time theRectangle(3,5)
andRectangle(2,4)
commands execute, the__init__
method is automatically called. WhenRectangle(3,5)
executes, the length and width attributes for examp1 are set to the input values and, similarly forexamp2
whenRectangle(2,4)
executes. Therefore, the__init__
method is responsible for initializing the attribute values whereself
is the object being referred to at the time of execution (you may see others refer to the__init__
method as a constructor). Hence, it is possible to create multiple instances from the same class. This is the beauty of object-oriented programming: each instance has its own attribute values and can reference methods available within the class definition.One more important point about methods internal to a class definition must be noted. Bear in mind that
self
refers to the object currently being operated upon. When a method is called to operate upon an object, observe thatself
is an implicit parameter that is not explicitly passed. For example, in the main code,examp1=Rectangle(3,5)
instantiates an object by automatically calling the__init__
method. Notice that there are two arguments passed in the Rectangle(3,5) statement. On the other hand, inside the class definition, the__init__
method has three input arguments including self which must appear first on the input argument list. As another example, consider theexamp1.rescale(2)
command. In this case, the input parameter is the value used to rescale the length and width attribute values internal to theexamp1
object. Observe that, internal to the class definition, the rescale method has two input arguments. Again, theself
argument is implicit and appears first while the scale parameter is explicitly set by the method call in the main code. Whenever a method is to be called to operate upon an object, the method definition must haveself
as the first input argument. After that, all subsequent input arguments should refer to parameters used within the method.The
__del__
dunder method is referred to as the destructor and is responsible for deleting the object when its use has expired. The subject of destructors is often omitted in introductory courses. However, professional coding demands efficient memory management so that if an object is no longer being used, best practices require its removal from memory. In the above example, redefiningexamp1
as an integer automatically causes the destructor to run as the object has been overwritten. Thedel
command can be used to delete a variable; hence, the destructor would run upon deletingexamp2
.The
__str__
method enables theprint(examp1)
command to make sense. Under normal operating circumstances, Python has no idea how to print objects. If no guidance is given, Python simply outputs a 'handle' that can be used to deduce the object's location in memory. This kind of information would not be useful to a high-level programmer. The__str__
method basically gives guidance on how to apply theprint
command.Magic methods are incredibly useful in this way because they execute in response to some action. The
__init__
method runs automatically when an object is instantiated, the__del__
method automatically executes when an object is removed and the__str__
method automatically executes when a desired string operation on an object is referred to.To conclude, you now have a working knowledge of the following terms: class, object, instantiation, self, constructor, destructor, method, and magic method. In addition, you also know how to define a class and instantiate objects with respect to a class. Practice more examples to become comfortable with object-oriented programming.
- The keyword
Read this for more on creating classes and methods.
Python is packed with a vast set of magic methods. Before delving deeper into class constructions, it is a good idea to gain some more perspective on this subject.
This video demonstrates class construction with a balanced mix of magic methods and user-defined methods. You may need to refer back to the Basic Terminology section to understand how the
__add__
and__str__
magic methods are being used.
10.3: Derived Classes
Classes and their associated methods are incredibly useful because of their reusability. Consider the case where we want to create a
Square
class that operates on squares. Given that theRectangle
class already exists, it should be possible for theSquare
class to inherit some of the computational capabilities of theRectangle
class presented in Section 10.2 since a square is a kind of rectangle. Whenever one class is a kind of another class, inheritance should be possible. This relationship is referred to as IS-A. Under these circumstances, a child class (e.g.Square
) can inherit the use of various methods from the parent class (e.g.Rectangle
).Try inserting this class definition to the code from Section 10.2, which should follow directly after the
Rectangle
class definition.class Square(Rectangle): def apratio(self): return .25*self.length
Then add this code to your main code:
examp3=Square(2,2) print(examp3.area()) print(examp3.perimeter()) print(examp3.apratio())
There are several points to note regarding the syntax and usage of inherited classes:
The syntax class
Square(Rectangle)
means thatSquare
is the child class andRectangle
is the parent classSquare
has no__init__
method. The objectexamp3
, which is of theSquare
class, is allowed to use the__init__
method from theRectangle
parent class.Square
also inherits the ability to use other parent methods, such asperimeter
andarea
. Study these examples to practice inheritance.Read this for more on inheritance.
The inheritance examples we've looked at so far have been short so that we can get the basic points across. Consider this example to practice working with a larger-scale object-oriented program.
10.4: Applying Object-Oriented Programming
- This is an excellent example of boolean operations like AND, OR, and NOT. Following and implementing this example in Repl.it will help you review the OOP concepts in this unit.
Unit 10 Assessment
- Receive a grade
Take this assessment to see how well you understood this unit.
- This assessment does not count towards your grade. It is just for practice!
- You will see the correct answers when you submit your answers. Use this to help you study for the final exam!
- You can take this assessment as many times as you want, whenever you want.