Exploring Classes & Objects in Python

Exploring Classes & Objects in Python
Exploring Classes & Objects in Python

In this tutorial, we are going to learn about Python as an Object-Oriented Programming(OOP) language. We are also going to see some fundamental concepts in OOP with the help of examples.

As we all know that python is a high-level programming language which is designed for general-purpose programming. Python supports both Object-Oriented and Procedural Programming approaches. We can easily implement Object-Oriented Programming concepts like Class, Object, Encapsulation, Polymorphism and Inheritance in Python. At the same time, we can also create Procedural Programs by using for and while loop in python.

Object-Oriented Programming

One of the most popular approaches to solve a programming problem is using Object-Oriented Programming.

An object has two main characteristics:

  1. Attributes
  2. Behaviour

Let’s take a very simple example to understand this concept in a better way. A student can be an object, as it may have the following properties:

  1. Name, Age, Color, Race as attributes.
  2. Working, Studying, Sleeping, Walking as behaviour.

Let’s understand some basic OOP concepts in python.

Class:

A class can be considered as a user defined blueprint from which our objects are created. Classes are used to bundle data and functionalities together so that it’s objects can be created or classified under different classes based on their functionalities. Each class can have their own attributes to maintain the state and classes can also have methods to modify its state values.

Let’s try to understand the need of class with an example.

Let’s say you want to track down the number of cars that belong to a certain company. A car can have many different attributes like color, model number, engine type and price. Suppose we have stored the cars with their attributes in a list, then how would we know which car belongs to which company. And what if we want to add more features for a certain car? To resolve the issue of lack of organization in a car we use classes.

We can create user-defined structures using classes so that we can create data members and member functions. We can access these data and functions by creating an instance of the class. So we can say that it’s like a blueprint of an object.

Key Points For Class:

  • Classes are created using keyword class
  • Attributes are nothing but variables of a class
  • Attributes can be accessed by using (.) dot operator

Syntax of Class:

class className:
#statement-1
#statement-2
.
.
.
#statement-n

Example of class Dog:

How to define a class:

class Car:
pass

Here, we use the class keyword to define an empty class Car. From class, we can create instances. An instance is a specific object created from a particular class.

Objects:

A class is the blueprint of an object, while an object is an instance of the class with real live values. For example, Our class is Car, while the object we created can be Tesla, BMW, Jeep etc. We can have as many objects as we want, but without the main class we may lose our main track and lose some information, that’s why classes are so important in any programming language.

Simple example of creating class and object:

Create a class:

class myClass:
var = 10

Create an object:

obj = myClass()

Printing the value of the variable:

print(“Value of object: “,obj.var)

Output:

 

Understanding the init() function

The examples we saw above were in their simplest form and they are not actually very helpful in solving programming problems in real life. In real life programming problems, we use the init() function. All classes have this built-in function called init(), which are always executed when we create an object. We use init() function to assign values to object properties or other operations which are necessary to run when we create an object.

#Functional example demonstrating class and object:

#Create a class:

class Car:

    def __init__(self,company,model,color):

        #Assigning values to attribute

        self.company = company

        self.model = model

        self.color = color

#Create an object:        

c1 = Car(“TATA”,”Tigor”,”Black”)

#Print feature values:

print(“Company Name: “,c1.company)

print(“Model Name: “,c1.model)

print(“Color :”,c1.color)

Output:

Object Methods

Objects can also contain methods. All the objects created under the same class can access the methods. 

#Class with method:

#Create a class:

class Car:

    def __init__(self,company,model,color):

        #Assigning values to attribute

        self.company = company

        self.model = model

        self.color = color

    def func(self,name):

        print(“Hello, My name is “,name)

#Create an object:        

c1 = Car(“TATA”,”Tigor”,”Black”)

#Print feature values:

print(“Company Name: “,c1.company)

print(“Model Name: “,c1.model)

print(“Color :”,c1.color)

print(“\n”)

#Calling the function:

c1.func(“Pratik Shukla”)

Output:

We can create more than one methods for the same class.

The method can also have zero arguments.

#Creating class with multiple methods:

#Create a class:

class Car:

    def __init__(self,company,model,color):

        #Assigning values to attribute

        self.company = company

        self.model = model

        self.color = color

    def func(self,name):

        print(“Hello, My name is “,name)

    def func2(self):

        print(“Hey, I belong to :”,self.company)

#Create an object:        

c1 = Car(“TATA”,”Tigor”,”Black”)

#Print feature values:

print(“Company Name: “,c1.company)

print(“Model Name: “,c1.model)

print(“Color :”,c1.color)

print(“\n”)

#Calling the function:

c1.func(“Pratik Shukla”)

#Calling the other function:

c1.func2()

Output:

Understanding the self Parameter

The self parameter is used as a reference to the current instance of the class. By using a self parameter we can access variables of the class. We can name that parameter whatever we want. But we must keep it as the first parameter in case we have multiple parameters.

#Understanding self parameter:

#Create a class:

class Person:

    def __init__(sky,name):

        #Assigning values to attribute

        sky.name = name

    def func(planet):

        print(“Hey, I’m “,planet.name)

#Create an object:        

p1 = Person(“Pratik”)

#Print feature values:

print(“Name: “,p1.name)

#Calling the function:

p1.func()

Output:

Modifying object Properties

We can easily modify the public properties of class. But we can’t modify the private variables or methods of a certain class. We’ll see about this later in the Encapsulation topic.

#Modifying the properties:

#Create a class:

class Person:

    def __init__(self,name,age):

        #Assigning values to attribute

        self.name = name

        self.age = age

#Create an object:        

p1 = Person(“Pratik”,20)

#Print feature values:

print(“Age :”,p1.age)

#Modifying age:

p1.age = 22

#Printing modified age:

print(“Age :”,p1.age)

Output:

Deleting Attributes of Object

If we don’t need a certain attribute or property of an object, we can delete it.

#Deleting an attribute:

#Create a class:

class Person:

    def __init__(self,name,age):

        #Assigning values to attribute

        self.name = name

        self.age = age

#Create an object:        

p1 = Person(“Pratik”,20)

#Print feature values:

print(“Age :”,p1.age)

#deleting an attribute:

del p1.age

#Printing deleted attribute:

print(“Age :”,p1.age)

Output:

Here we can see that after deleting an attribute,if we try to call that property we get an error.

Deleting Objects

If we want to delete an object itself, we can also do that by using del.

#Deleting an object:

#Create a class:

class Person:

    def __init__(self,name):

        #Assigning values to attribute

        self.name = name

#Create an object:        

p1 = Person(“Pratik”)

#Deleting object:

del p1

#Calling attribute of deleted object:

print(p1.name)

Output:

After deleting an object, if we try to call it we get an error.

The Pass Statement

There will be some cases where we don’t have any content to write in the main class. In that case we need to write a pass statement.

#Pass Statement:

#create a class:

class person:

    pass

p = person()

Inheritance:

In inheritance, we create a new class using the details of an already existing class without changing its content. Here the newly formed class is called the Child class and the original class is called the parent class. By using inheritance we can use the functions and attributes of parent class in child class.

#Inheritance:

#Create a parent class:

class Animal:

    def __init__(self):

        print(“This is an animal”)

    def eat(self):

        print(“I can eat!”)

    def run(self):

        print(“I can run!”)

#Inheriting the parent class:

class Dog(Animal):

    def __init__(self):

        print(“I am Dog!”)

    def bark(self):

        print(“I can bark!”)

#Creating an object:

d1 = Dog()

#Calling parent class methods:

d1.eat()

d1.run()

#Calling parent class method:

d1.bark()

Output:

In the above example we can see that we can use the methods of parent class (Animal) in child class (Dog).

Using the parent class’s __init__() method:

If we also want to use the parent class __init__() method we have to use super().__init() method. This will first go to the parent class and then it will be back at child class method.

#Inheritance:

#Create a parent class:

class Animal:

    def __init__(self):

        print(“This is an animal”)

    def eat(self):

        print(“I can eat!”)

    def run(self):

        print(“I can run!”)

#Inheriting the parent class:

class Dog(Animal):

    def __init__(self):

        super().__init__()

        print(“I am Dog!”)

    def bark(self):

        print(“I can bark!”)

#Creating an object:

d1 = Dog()

#Calling parent class methods:

d1.eat()

d1.run()

#Calling parent class method:

d1.bark()

Output:

Encapsulation:

There will be certain cases where we don’t want users to modify the variables. To do so we use encapsulation. By using encapsulation we restrict access to certain methods or variables. In python, we use _(single) or __(double) to denote a private variable.

#Encapsulation:

#Creating class:

class Pen:

    def __init__(self):

        self.__MRP = 10

    def selling_price(self):

        print(“Selling price for pen is: “,self.__MRP)

    def set_max_price(self,price):

        self.__MRP = price

#Creating an object:        

p = Pen()

#Printing the pen price:

p.selling_price()

#changing the price:

p.__MRP = 20

#Printing the pen price:

p.selling_price()

#Using the setter function:

p.set_max_price(20)

#Printing the pen price:

p.selling_price()

Output:

In the above example we can see that if the user tries to change the value of the private variable __MRP, they won’t get the desired output. To actually change the value of private variables we use setter methods as mentioned in the example.

Polymorphism:

Polymorphism is a very useful ability of Object-Oriented Programming(OOP) that allows us to use a common interface for multiple forms. Suppose we have classes with the same method name but different content, we can use polymorphism here to call specific methods.

#Polymorphism:

#Creating class Dog:

class Dog:

    def run(self):

        print(“Dogs can run fast!”)

    def drink(self):

        print(“Dogs drink milk!”)

#Creating class Turtle:

class Turtle:

    def run(self):

        print(“Turtles can’t run fast!”)

    def drink(self):

        print(“Turtles don’t drink milk!”)

#Creating class Cat:

class Cat():

    def run(self):

        print(“Cats can run fast!”)

    def drink(self):

        print(“Cats drink milk!”)

#Creating common interface for test1:

def running_test(animal):

    animal.run()

#Creating common interface for test2:

def drinking_test(animal):

    animal.drink()

#Creating objects:   

d = Dog()

t = Turtle()

c = Cat()

#Passing the object in common interface:

running_test(d)

drinking_test(t)

running_test(c)

Output :

In the above function, we can see that we have three different classes that have the same method names, but there is different content in each of them. So here we have created two different interfaces that help us call each of the methods as required by passing an object of a particular class. To call the run() function, we use the running_test() common interface. To call the drink() function, we use the drinking_test() common interface.

You can run and download the code from Google Collaboratory.

Enjoyed reading this article? Explore more on Python, here.

By Pratik Shukla