OOP stands for Object Oriented Programming. This concept is a style of solving programming problems where properties and behavior of a real-life object is packaged as a single entity in the code.
This style of coding enables modularizing and scaling with least amount of issues.
Python is a dynamically typed, high level interpreted programming language. Python supports several OOP features including the following:
- Classes and Objects
1. Classes in Python
Class is a blueprint of the real-life entity. In Python, it is created using the class keyword as shown in the following code snippet.
class Person: def __init__(self, name, age): self.name = name self.age = age
In the above:
- class – Here is a class named Person.
- Constructors have the default name __init__. They are functions that are implicitly called when an object of the class is created.
- All instance methods including the constructor have their first parameter as self.
- self refers to instance that is being referenced while calling the method.
- name and age are the instance variables.
If you are new to Python, refer to this: Python Introduction Tutorial – Variable, String, Function Examples
2. Objects in Python
Once a Person class is defined you can use it to create an instance by passing values as shown below.
class Person: def __init__(self, name, age): self.name = name self.age = age if __name__ == "__main__": p = Person("ranjeeta", 23) print(p.name)
In the above:
- p – is the name of the object that we are creating based on Person class
- Even though the class has three parameters (self, name, age), we’ll still pass only name and age while creating an object, as we don’t need to refer self here. It’s implicit.
- Once an object is created, you can refer to the attributes of the object using a dot. For example, p.name refers to the name attribute of that particular object
3. Inheritance in Python
As the name suggest, this concept is about inheriting properties from an existing entity. This increases reusability of code. Single, Multiple and Multi-level inheritances are few of the many types supported by Python.
The following example shows how to use inheritance in python:
class Person: def __init__(self): pass # Single level inheritance class Employee(Person): def __init__(self): pass # Multi-level inheritance class Manager(Employee): def __init__(self): pass # Multiple Inheritance class Enterprenaur(Person, Employee): def __init__(self): pass
In multiple inheritance, classes are inherited from left to right inside parenthesis, depending on Method Resolution Order (MRO) algorithm of Python.
4. Encapsulation in Python
It is the concept of wrapping data such that the outer world has access only to exposed properties. Some properties can be hidden to reduce vulnerability. This is an implementation of data hiding. For example, you want buy a pair of trousers from an online site. The data that you want is its cost and availability. The number of items present and their location is information that you are not bothered about. Hence it is hidden.
In Python this is implemented by creating private, protected and public instance variables and methods.
Private properties have double underscore (__) in the start, while protected properties have single underscore (_). By default, all other variable and methods are public.
Private properties are accessible from within the class only and are not available for child class(if inherited). Protected properties are accessible from within the class but are available to child class as well. All these restrictions are removed for public properties.
The following code snippets is an example of this concept:
class Person: def __init__(self, name, age): self.name = name self.age = age def _protected_method(self): print("protected method") def __private_method(self): print("privated method") if __name__ == "__main__": p = Person("mohan", 23) p._protected_method() # shows a warning p.__private_method() # throws Attribute error saying no such method exists
5. Polymorphism in Python
This is a concept where a function can take multiple forms depending on the number of arguments or type of arguments given to the function.
class Person: def __init__(self, name, age): self.name = name self.age = age def show_salary(self): print("Salary is unknown") class Employee(Person): def __init__(self, name, age, salary): super().__init__(name, age) self.salary = salary def show_salary(self): print("Salary is", self.salary) if __name__ == "__main__": p = Person("y", 23) x = Employee("x", 20, 100000) p.show_salary() # Salary is unknown x.show_salary() # Salary is 100000
In the above example, super keyword is used to call a method of parent class. Both classes have the method show_salary. Depending on the object type that makes a call to this function, the output varies.
Python has inbuilt-polymorphism functions as well. One of the simplest examples is the print function in python.
print("Hello there", end=" ") print("I am Aanisha") print(len([1, 2, 3, 4, 5]))
Output of the above code will be:
Hello there I am Aanisha 5
In the above code snippet:
- The end keyword parameter changed the functionality of print function. Hence it did not end ‘Hello There’ with an end-line.
- len([1, 2, 3, 4, 5]) in third line return an int. The print recognizes the data type and implicitly converts it to string and prints it to the console.