Python is an object-oriented programming language. Unlike procedure-oriented programming, where the main emphasis is on functions, object-oriented programming stresses on objects. A class is a user defined blueprint or prototype from which objects are created. Classes provide a means of bundling data and functionality together. Creating a new class creates a new type of object, allowing new instances of that type to be made. An object is simply a collection of data (variables) and methods (functions) that act on those data. Consider this example :
In the above picture a Car class is defined and it is mentioned in the class definition that car will have properties like make, model and color and behaviors like start, stop , speed up , speed down, break etc. So whenever an object/instance of this class is created they will have some properties and behaviours.
1) Defining a Class in Python
In Python all class definitions start with the class keyword, which is followed by the name of the class and a colon. It is a general convention that class name start with a capital character. Any code that is indented below the class definition is considered part of the class’s body. i.e:
class ClassName():
# Statement
# Note : We can ommit () after classname as in current versions of Python it is acceptable to declare like this class ClassName:
2) Creating an Instance of Class
An Object is an instance of a class. A class is like a blueprint while an instance is a copy of the class with actual values. An object consists of :
State: It is represented by the attributes of an object. It also reflects the properties of an object.
Behaviour: It is represented by the methods of an object. It also reflects the response of an object to other objects.
Identity: It gives a unique name to an object and enables one object to interact with other objects.
To create an instance / object of a class we write the object name followed by assignment operator and then class name(). Consider the following example:
# Class Definition
class Car():
pass
# Car class instance/object creation
car1=Car()
print(type(car1))
# The output of the above mentioned code will be
<class '__main__.Car'>
3) Constructor Function in Python
Class functions that begin with double underscore __ are called special functions as they have special meaning. Of one particular interest is the init() function. This special function is called whenever a new object of that class is instantiated. All classes have this init() function and it is always executed when the class is being initiated. We use the init() function to assign values to object properties, or other operations that are necessary to do when the object is being created.
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
p1 = Person("John", 36)
print(p1.name)
print(p1.age)
In the example mentioned above we have created a constructor. The first parameter is self which will be given in all methods/functions of the class. In python it is mandatory to pass self as first parameter of all methods. As we have created constructor which require two values other then self so during creation of object we must pass two values in the constructor otherwise Python will generate an error.
4) Adding Methods in Class
We can create methods in a class to specify actions / tasks to perform. Consider an other example:
class Car:
### Car Attributes
def __init__(self, make, model,year):
self._make = make
self._model = model
self._year=year
# Car Behaviours
def descriptionCar(self):
print(f"The Care make is {self._make}")
print(f"The Care model is {self._model}")
print(f"The Care year is {self._year}")
def move(self):
print(f" {self._make} is moving..")
def brake(self):
print(f"{self._make} {self._model} has applied brakes..")
car1=Car("Toyota","Yaris", "2020")
car2=Car("Honda","City","2021")
# We can access any property of Class
print(car1._make )
car1.descriptionCar()
car1.move()
car2.descriptionCar()
car2.brake()
In the above mentioned code we have defined a class that takes 3 parameters during creation of an object. Then the object attributes can be accessed using object_name.attribute_name . Similarly we can access any method of the object using object_name.method_name().
5) Encapsulation in Python
Encapsulation is one of the fundamental concepts of object-oriented programming (OOP). It allows the wrapping of data and the methods that work on data within one unit. This puts restrictions on accessing variables and methods directly and can prevent the accidental modification of data. To prevent accidental change, an object’s variable can only be changed by an object’s method. Those types of variables are known as private variables.
Encapsulation can be achieved by declaring the data members and methods of a class either as private or protected. But In Python, we don’t have direct access modifiers like public, private, and protected. We can achieve this by using single underscore and double underscores. Access modifiers limit access to the variables and methods of a class. Python provides three types of access modifiers private, public, and protected. Consider the picture shown below.
Protected members (in C++ and JAVA) are those members of the class that cannot be accessed outside the class but can be accessed from within the class and its subclasses. To accomplish this in Python, just follow the convention by prefixing the name of the member by a single underscore “_”. Although the protected variable can be accessed out of the class as well as in the derived class(modified too in derived class), it is customary(convention not a rule) to not access the protected out the class body.
Private members are similar to protected members, the difference is that the class members declared private should neither be accessed outside the class nor by any base class. In Python, there is no existence of Private instance variables that cannot be accessed except inside a class. However, to define a private member prefix the member name with double underscore “__”. Note: Python’s private and protected members can be accessed outside the class through python
class Employee:
# constructor
def __init__(self, name, yob, salary):
# public data member
self.name = name
# protected member
self._yob = yob
# private member
self.__salary = salary
# creating object of a class
emp = Employee('Jessa',1982, 10000)
# accessing private data members
print('Salary:', emp.name)
# Although Accesible but Should not be done due to convention
print('Year of Birth:', emp._yob)
# Not accessible outside the class using normal method
# Python Will Generate error
#print('Salary:', emp.__salary)
# But Python Also provides a method to access Private attributes as
print('Salary : ' , emp._Employee__salary)
# Similarly Python also allows to change values of private attributes as
emp._Employee__salary=500
# But these should not be used so that OOPs Conventions remain fullfiled
6) Python Inheritance
Inheritance allows us to define a class that inherits all the methods and properties from another class. Parent class is the class being inherited from, also called base class. Child class is the class that inherits from another class, also called derived class. Inheritance enables us to define a class that takes all the functionality from a parent class and allows us to add more. Consider the following example :
# Parent Class
class Person():
# Constructor
def __init__(self, name, id):
self.name = name
self.id = id
# To check if this person is an employee
def Display(self):
print(self.name, self.id)
# Code to Create Objects
emp = Person("Ali", 102) # An Object of Person
emp.Display()
# The output of the code will be
Ali 102
Creating a Child Class
class Emp(Person):
def Print(self):
print("Emp class called")
Emp_details = Emp("Mayank", 103)
# calling parent class function
Emp_details.Display()
# Calling child class function
Emp_details.Print()
# The output of the code will be
Mayank 103
Emp class called
# Note : The Person class must be first defined before the creation of the child class