Object-oriented programming is an important topic that many people skip. You must learn OOP to build apps and do advanced-level programming. If you do not know the fundamentals of object-oriented programming, I’ll help you understand it easily.
Before we learn object-oriented programming, make sure you have polished your Python basics knowledge. If you aren’t comfortable with Python, I suggest you learn it from this article before learning OOP. If you know the basics, let’s move ahead.
There are mainly two types of programming paradigms; procedure-oriented programming and object-oriented programming (which is what we call OOP). Let’s see what object-oriented programming is.
What Is Object-Oriented Programming?
Object-oriented programming (OOP) is a programming paradigm based on the concept of objects and data. We treat every entity as an object in OOP.
Just like we call everything we see in real life as objects, we call an entity in OOP an object.
Classes in Python
If you are coming from a computer science background, you might have heard about classes either in Java or C++ or some other programming languages. Let’s see what a class actually is in object-oriented programming.
A class can be defined as an object’s blueprint, description, or definition. We can use the same class as a blueprint for creating multiple different objects.
Classes are created using the keyword ‘Class’ and an intended block, which contains class methods.
A class can contain attributes and methods. Attributes are the variables that are defined within the class. Methods are similar to functions. It’s just that we call functions as methods in object-oriented programming.
The __init__ Method
__init__ method stands for the initialization method. Every class definition in Python should start with the __init__ method.
The __init__ method is called when an object of the class is created. This method is the constructor of the class.
A constructor is a method that we can use to initialize a new object. This method is called instantly after the memory allocation takes place for the new object.
We can use the constructor to initialize objects to certain values, either desired ones or default ones when the object is created.
We should use ‘self’ as the first parameter for all methods. This parameter refers to the instance that is calling the method. Attributes are pieces of data associated with instances of a class.
Let’s see an example of a Python class with an __init__ method.
class Student: def __init__(self,name,grade): self.name = name self.grade = grade john = Student('John',85) bob = Student('Bob',91) print(bob.name) print(bob.grade)
This example shows a class whose name is Student. It has an __init__ method with two additional parameters along with self, name, and grade. That means, this class takes the name and grade of a student as its parameters.
The arguments passed to the function are then assigned to the variables of self. Here, the self contains two variables that are, self.name and self.grade.
john and bob are two objects created by the class Student.
The constructor Student() is called while creating the objects, and this will invoke the __init__ method inside the Student class.
Note that two arguments are passed while we created the object. Then, we printed the name and grade of one student, that is, bob.
The output of this code will be: Bob 91
Methods in Python
Now we know about the __init__ method pretty well. But there can be other methods as well. Just like we define functions in Python, we can define methods inside classes too. Let’ see how we can do that.
Classes can have methods defined by the programmer to add functionality to them. Note that all methods should have ‘self’ as their first parameter.
Let’s see an example of this scenario.
class Student: def __init__(self,name): self.name = name def sayHello(self): print("Hello.. I'm "+self.name) elisa = Student(" Elisa ") elisa.sayHello()
In this example, note that we defined a method with the name sayHello. This method just prints a greeting message with the name of the person.
When we create the object, we pass the name of the person as an argument. That is received by the __init__ method and then it is used by the sayHello method to print the name along with “Hello”.
This program will produce an output like this: Hello.. I’m Elisa
Class variables vs Instance variables
We can access a variable defined in a class by using the class name, which is known as a class variable, or by using the object name, which is called an instance variable.
Let’s see an example.
class Blog: url = 'www.pythonistaplanet.com' def __init__(self, name): self.name = name tutorial = Blog("My Blog") print(tutorial.name) print(Blog.url)
In this example, “url” is a class variable and “name” is an instance variable.
This program will produce the following output:
Now, we have learned some basic concepts of object-oriented programming in Python. Now, let’s move to some advanced concepts like inheritance, polymorphism, encapsulation, etc.
Inheritance in Python
What is inheritance?
The process of deriving a new class from an old class (parent class) is known as inheritance. The old class is called the superclass and the new one is called the subclass. The subclass can use all the stuff that is inside a superclass.
Let’s understand inheritance with the following example.
Let’s say we have a class called Animal. Also, we have one more class called Cat. In this case, the Animal class is the superclass and Cat is its subclass. That means Cat belongs to Animal. So, Cat has all the powers of Animal.
In Python, that corresponds to Cat class having access to all the variables and methods of Animal. Cat can access them all. But Animal can’t access the property of Cat.
Did you get the point? Basically, all it means is, a Cat is an Animal but an Animal is not a Cat.
Let’s see one example code.
class Animal: def __init__(self,name,color): self.name = name self.color = color class Cat(Animal): def meow(self): print("Meow...") liza = Cat("Liza","Orange") print(liza.color) liza.meow()
This code will give the following output:
Here, in this example, you can see that the Animal class has two properties, which are name and color. When the new object, called liza was created, we passed both these properties as arguments.
A Cat object can access both name and color variables. Also, we printed the color of liza on the 10th line.
The Cat class has its own method too, that is meow(). The liza object can access that as well.
Inheritance can also be indirect. One class can inherit from another, and that class can inherit from a third class.
The function super() is a useful inheritance-related function that refers to the parent class. We can use it to find the method with a particular name in an object’s superclass.
Syntax : super().method_name
When we call any method using super(), the method in the superclass will be called even if there is a method with the same name in the subclass.
Now, it’s time to move on to the next topic in OOP, which is polymorphism.
Polymorphism in Python
What is polymorphism?
Polymorphism is the property by which objects belonging to different classes are able to respond to the same message but in different ways.
Polymorphism can be carried out through inheritance, with subclasses making use of superclass methods or overriding them so that the same method works differently based on the object that we are working with.
That means, we can have two or more methods in superclass and subclass all of them having the same method name. Even if they have the same name, they can be used separately according to our needs.
Let’s see an example.
class Fruit: def __init__(self,name): self.name = name def love(self): pass #pass means do nothing class Mango(Fruit): def love(self): print(" Katrina love mangoes") class Apple(Fruit): def love(self): print(" Adam loves apples") slice = Mango("Alphonso") slice.love() appy = Apple(" Kashmiri ") appy.love()
This program will produce the following output:
Katrina loves mangoes
Adam loves apples
In this example, you can see that there are three different classes. Fruit is the parent class or superclass. Fruit has two subclasses which are Mango and Apple.
All these three classes contain a method called love(). But, this method works differently for each class.
When we create the object of Mango and call the love() method, the method defined inside Mango class will execute. Similar is the case for Apple also.
That is how methods having the same name works differently for different objects. This concept is known as polymorphism in OOP.
Concepts like operator overloading and function overloading are parts of polymorphism. If you are interested in learning more about these concepts, check out this article.
What is encapsulation?
Encapsulation is used to restrict access to methods and variables. The code and data are enclosed within a single unit, just like a capsule, from being modified by external agents.
We can specifically define which are the variables and methods that we need to define as public and private. We can restrict access to private attributes using encapsulation, so no one can alter them.
In Python, we can define a private attribute using an underscore as the prefix (either single “ _ “ or double “ __“ ).
Let’s see an example.
class Employee: def __init__(self): self.__salary = 27000 def showSalary(self): print(self.__salary) def setSalary(self, salary): self.__salary = salary john = Employee() john.showSalary() john.salary = 30000 john.showSalary() john.setSalary(30000) john.showSalary()
The output of this program will be:
In this case, the variable salary is set as private using the underscore as the prefix. Since it is private, only the object of the class, that this method belongs to, can use this. First, we printed the salary of the object john, which is defined inside the class.
Then, we tried to change the salary from outside the class. But look at the output, it is still 27000. That is because we can’t access a private variable from outside a class.
But the third time, we tried to change the salary and set it to a new value using a setter function. This time, the salary got changed to 30000.
So, we can only access a private variable using a method of its own class. We can’t access it simply from outside the class.
This concept is called encapsulation in OOP.
Advantages of OOP in Python
Let’s see some of the advantages of object-oriented programming in Python.
Here goes a few of them:
- We can easily reuse the objects that we create.
- Once a program reaches a certain size, OOP based programs are actually easier to code than other types of programs.
- An object-oriented program is a lot easier to modify and also, it is easy to maintain existing codes.
- OOP is used in several Python frameworks and libraries.
Object-oriented programming is an essential skill to have under your belt. It will be very helpful while solving certain kinds of problems.
As you code more and learn more advanced topics, you will be able to find out when and where to use object-oriented programming.
I’ve prepared a quick and simple infographic about object-oriented programming concepts in Python. You can download it from the link given below.
In this tutorial, we learned one of the important concepts in Python, which is object-oriented programming (OOP).
Objects, classes, and methods are the major things that we use in OOP. Object-oriented programming helps to implement many functionalities like inheritance and polymorphism in Python.
For large and complex problems, OOP is usually most suited rather than the procedural way of programming.
If you want to create desktop apps using Python OOP, I highly recommend you learn Tkinter. It is super-easy to learn for beginners. I’ve written a helpful guide on learning Tkinter and building 3 cool apps. Click here to check it out.
If you have any doubts, feel free to let me know in the comments. I’ll be happy to help you.
If you find this tutorial useful, share this article on social media so that it may help someone else as well.