9: Introduction Object-Oriented Programming: Classes and Objects
- WFU Robotics
- Aug 6, 2020
- 5 min read
Updated: Mar 8, 2021
So far we have covered the core data types: strings, ints, floats, lists, tuples, and dictionaries. There is still one more major data structure in Python, classes. Classes are unlike all the above data types. They are much more flexible and powerful, but with this great power comes great terminology. If you have learned about object-oriented programming in other languages, such as Java or C++, this terminology will be familiar for you. If you have not, do not worry, I will try to explain each of these concepts enough so that you can at least gain a basic understanding. Once again, the best way to learn is by going into your IDE and implementing these concepts yourself. I will also provide extra learning resources for each section.
Classes are how we group together data of similar types, with similar attributes, while still allowing their characteristics to be individualized within the group. As an example, think about dogs. All dogs share certain characteristics, such as four legs, a head, a tail, a breed, and whatever else is inherent to being a dog. However, there is still variance in these characteristics. While all dogs have a breed, not all dogs are the same breed. While all dogs have a tail, some are long, and some are short. While all dogs exist in physical space, some take up more of it, and some less. We can think of dogs as a whole as a class, and each individual dog as an object of that class. Generally, a class describes a group of data which is similar in some way, and all objects belonging to that class will share characteristics of other objects of the class, but the values of those characteristics are not necessarily the same.
In fact, we have already seen many objects of many different classes in this tutorial. In Python, every data type is an object. Integer numbers are members of the Int class, and that class says that those integers can interact in certain ways, such as be added, subtracted, multiplied, and divided together, and the class also defines how exactly these interactions should take place, and what their outputs should be. As we saw in the last tutorial, lists are objects of the List class. Classes not only assign characteristics to their objects, but also control and define how they interact, and what they can do. We have already learned how to use some of Python’s built in classes, but now we will learn how to implement our own classes.
Let’s first look at a very basic example of how we define a class, and create some objects of that class:
class dog:
def __init__(self, tail_length, breed):
self.tail_len = tail_length
self.breed = breed
self.num_legs = 4
collie = dog(8, "border collie")
lab = dog(12, "black lab")
print(collie.breed)
print(lab.tail_len)
print(collie.num_legs)
>>border collie
12
4
The definition of our class, dog, starts with the keyword “class”, followed by the name of our class (no spaces), and then a colon. After that, we define a function called “__init__”, a function which must be included in each class we make, known as the constructor.
The constructor is a function, which must be implemented in each class, and is called automatically by Python whenever we create an object of that class. Its name must be “__init__”, those are two underscores on either side of the term “init”. This declaration will let Python know that this function is the constructor. Each constructor must have at least one parameter, the self parameter.
Self is a keyword which must be included as a parameter in every function defined inside a class. It represents the object which is calling this function. In my_list.append(0), my_list would be automatically passed into the append() function as the argument for the self parameter. In our above example, the object “collie” would be passed into the constructor for the self parameter. Using the self parameter, we can assign different characteristics, or attributes, to a specific object of a class.
The attributes in this example are “tail_len”, “breed”, and “num_legs”. When a class object is defined, such as when we create the objects “collie” and “lab”, it is given whatever attributes are specified inside the constructor. The values for those attributes can either be initialized through additional parameters of the constructor, which allows these values to be different among all objects of a class, or they can be specified without a parameter, in which case they will be initialized as the same value for every object of the class. “tail_len” and “breed” fall under the former category, since we specify their values at the time of construction, but “num_legs” falls into the latter, since we do not specify its value, rather it will always be initialized as 4.
We can access the values of these attributes through dot notation. Dot notation starts with the object whose attributes we want to access, adds a period (.), and then specifies the attribute we want the value of.
Along with attributes that can only belong to a member of a class, we can create functions that can only be called by a member of a class. These functions are called member functions, also called class methods, and are the bread and butter of classes. Here’s an example of a simple member function, which prints all the attributes of an object of the dog class:
class dog:
def __init__(self, tail_length, breed):
self.tail_len = tail_length
self.breed = breed
self.num_legs = 4
def print_attributes(self):
print("Tail Length:", self.tail_len, "Breed:",
self.breed, "Number of legs:", self.num_legs)
collie = dog(8, "border collie")
lab = dog(12, "black lab")
collie.print_attributes()
lab.print_attributes()
>>Tail Length: 8 Breed: border collie Number of legs: 4
Tail Length: 12 Breed: black lab Number of legs: 4
To define a member function, we define it with the same syntax as any function, but inside the code block of the class. Also, just as with the constructor, we must include the self parameter.
Inside member functions, we can access and change attributes of the object by accessing them with dot notation, with “self” taking the place of the object. Here, we only want to access the attributes, but if we were to change them in any way, those changes would stick, and we could access the new values at any point in the future. Here is an example of that:
class dog:
def __init__(self, tail_length, breed):
self.tail_len = tail_length
self.breed = breed
self.num_legs = 4
def print_attributes(self):
print("Tail Length:", self.tail_len, "Breed:",
self.breed, "Number of legs:", self.num_legs)
def has_surgery(self):
print("We had to amputate a leg :(")
self.num_legs = self.num_legs - 1
collie = dog(8, "border collie")
collie.print_attributes()
collie.has_surgery()
collie.print_attributes()
collie.has_surgery()
collie.print_attributes()
>>Tail Length: 8 Breed: border collie Number of legs: 4
We had to amputate a leg :(
Tail Length: 8 Breed: border collie Number of legs: 3
We had to amputate a leg :(
Tail Length: 8 Breed: border collie Number of legs: 2
Member functions are called through the same dot notation, but like other functions, we must include parentheses which can hold any parameters we specify (they are empty if there are no parameters other than self).
That concludes our introduction to class and object-oriented programming. There are other useful tools of classes, such as inheritance and operator overloading, but for now I will leave some useful links for these topics below in case you want to learn more. This tutorial should provide enough information about class and objects so that you can understand any future reading about them. Thanks for reading!
Other Resources on Classes:
Class Inheritance: https://www.digitalocean.com/community/tutorials/understanding-class-inheritance-in-python-3
Operator Overloading: https://realpython.com/operator-function-overloading/
Challenge Activities:
Create a Rectangle class. You should be able to specify the length and width dimensions of this rectangle. Then implement three functions which return the area of the rectangle, change the dimensions of the rectangle to whatever the user specifies, and prints whether the rectangle is a square or not.
Commenti