In this tutorial, you will master the fundamental concept of object oriented programming(OOPs). In addition, you will learn about objects, to define a class, what an instance is, etc with examples.
Python being a multi-paradigm programming language enables the developer to choose any approach he wishes for scripting including procedural, functional, imperative, and object-oriented styles.Object-oriented programming, often abbreviated to OOPS, is accepted universally because of its easiness and structural distinctiveness. As its name suggests, Objects are the pivot of the OOPS concept along with class. In other words, the foundations of object-oriented programming language are objects and classes.
Object-oriented programming is a programming paradigm that enables a way of structuring programs by using the idea of “objects”. Two important characteristics of objects are attributes and behaviors.
For example, a student can be an object with attributes like name, class, id_no, etc, and the behaviors such as talking, singing, dancing, etc. Similarly, a mobile phone can be represented as an object with attributes like name, model, color, etc, and behaviors like calling, messaging, uploading, downloading, etc.
In programming, an object can be used to represent data and methods associated with the code. By bundling attributes and behaviors into individual objects, the OOPS approach is facilitating neat and well-organized codes. In addition, it also reduces redundancy by enabling code reusability. The concept of focusing on code reusability is termed as “DRY” which means Don’t Repeat Code.
Before jumping into the details let see how Object-Oriented Programming differs from Procedural Oriented Programming.
Object-Oriented Programming | Procedural Oriented Programming. |
---|---|
Deals with data | Deals with algorithm |
Programs are divided into objects | Programs are divided into Functions |
Follows bottom-up approach | Follows top-down approach |
Objects can move freely within member functions | Data can move between functions within the program |
Contains access specifiers like private, public, and protected | Contains no access specifiers |
Supports inheritance | Does not support inheritance |
Supports overloading | Does not supports overloading |
Data hiding is possible | Data hiding is impossible |
Requires more memory | Requires less memory |
Highly Secure | Less secure |
Ex: C++,Java,Python etc | Ex: C,FORTRAN,Pascal etc |
In object-oriented programming, a class is a user-defined data structure used to create objects. Users can define a set of attributes and functions, referred to as methods, associated with the object in a class. The methods in a class identify the behavior and actions that an object created in the class needs to perform on its data. In short, we can say that a class is a collection of objects or a blueprint of objects defining attributes and methods in common.
So now you are well clear about what a class is. Now we will see how to define a class.
A class definition always begins with the keyword class followed by the class_name
and a colon. The body of the class is scripted below following the indentation rule.
The syntax is as follows:
class Class_name:
. . . . . . . .
class_body
#Here you can define all attributes and methods
. . . . . . . .
This tutorial will teach you to create a class named Student to store some of the basic features of a student like a name, age, id no and the qualities a student can have. Here is an example:
class Student:
#class attribute
Dept = 'Computer Science'
#instance attribute
def __init__(self,name,age):
self.name=name
self.age=age
Now, let's scrutinize the example to get more clarity on the concept of class. In this example,
class_name
Student.__init__()
. This method initializes the instance attributes as soon as the object is created. You can pass any number of parameters to .__init__
method however the point to be considered is the first parameter should always be a variable called self.
self.name = name
indicates the creation of an instance attribute named name to which the parameter value is assigned.self.age = age
denotes the creation of an instance attribute named__init__ ()
method. In our case, all students belong to the computer science department. Hence Dept
is declared as a class attribute just before.__init__()
method.In essence, a class attribute is used to define properties that hold the same value for all class instances whereas an instance attribute is used to define attributes that hold unique values for each class instance.
While writing a class in python, one must be careful about the indentation as indentation plays a vital role in structuring a program. You can find in the above example how structured each and every component is and how indentation is maintained :
In case if you fail to use the correct indentation you will receive an Indentation Error.
So we have defined the Student class now. Let's create some students which are the objects of the class.
An object, also known as an instance, is an instantiation of a class. To be more specific an object implies the instance of a class.
By defining a class we have only created the description for the object. No memory or space is allocated yet. To make it mean you need to instantiate an object. This can be accomplished by using the class_name followed by parentheses containing the values to be passed to.__init__()
method.
Syntax is :
obj = Class_name() #S1 = Student()
Where obj is an object of the class.
Now consider the scenario where you forgot to provide the parameters to be passed to.__init__()
method while instantiating the object. Python will simply raise an error called TypeError
as illustrated below.
class Student:
#class attribute
Dept = 'Computer Science'
#instance attribute
def __init__(self,name,age):
self.name=name
self.age=age
S1 = Student()
S2 = Student()
Output Error:
Traceback (most recent call last): File "oops_ex.py", line 11, inS1=Student() TypeError: __init__() missing 2 required positional arguments: 'name' and 'age'
To avoid this error you need to pass the parameters inside the parentheses while instantiating the object. The following example shows this:
class Student:
#class attribute
Dept = 'Computer Science'
#instance attribute
def __init__(self,name,age):
self.name=name
self.age=age
S1 = Student("Chris", 17)
S2 = Student("Debora",16)
In our example S1
and S2
are the two instances of the class.S1
is an object for the class containing two attributes Chris
and 17
. Similarly, S2
denotes the object of a class that contains two attributes Debora
and 16
.
Accessing attributes from a class is not at all a big task. Accessing can be done by using a dot operator along with the object. The following example shows the way of accessing both the instance attribute and class attribute.
Class attribute Dept is accessed using the object S1
with the help of a dot operator which outputs the result as Computer Science.
>>> print(S1.Dept)
Computer Science
Similarly, instance attributes can be accessed using the dot operator with the object. Refer to below for example to understand the concept.
class Student:
#class attribute
Dept = 'Computer Science'
#instance attribute
def __init__(self,name,age):
self.name=name
self.age=age
S1 = Student("Chris", 17)
S2 = Student("Debora",16)
print('Hi I am',S1.name,'and I am',S1.age,'years old')
print('Hi I am',S2.name,'and I am',S2.age,'years old')
Output:
Hi I am Chris and I am 17 years old Hi I am Debora and I am 16 years old
Here, S1.name
and S1.age
indicate the accessing of instance attributes name and age from the class for the instance S1
with the help of dot operator, which produces the result Chris
and 17
.Similarly S2.name
and S2.age
access the attributes for instance S2
.
In object-oriented programming, we can modify the attributes dynamically by adding new attributes, altering the attribute values, or by deleting the attributes themselves.
We have slightly modified our example by adding a new attribute S1.idno = 10001
. When you observe the example you can notice that the new attribute is not defined inside the class instead it is defined outside dynamically.
class Student:
Dept = 'Computer Science'
def __init__(self,name,age):
self.name=name
self.age=age
S1 = Student("Chris", 17)
S1.idno = 10001
print('Hi Iam',S1.name,'and Iam',S1.age,'years old holding idno:',S1.idno)
Output:
Hi Iam Chris and Iam 17 years old holding idno: 10001
It is also possible to alter the value of an attribute dynamically. See below the program where we have changed the .name attribute of S1
to Tom
which was previously assigned to Chris
. In a similar way modified the class attribute. Dept to Science from Computer Science.
class Student:
#class attribute
Dept = 'Computer Science'
#instance attribute
def __init__(self,name,age):
self.name=name
self.age=age
S1 = Student("Chris", 17)
S1.name ='Tom'
S1.Dept ='Science'
print('Hi I am',S1.name,'and I am',S1.age,'years old')
Output:
Hi Iam Tom and Iam 17 years old. Science
The salient point is that by default all custom objects are changeable. Specifically, we can say that mutable objects can be dynamically altered while immutable objects can’t be. So lists and dictionaries are changeable while strings and tuples are immutable.
You can also delete an attribute using the del
keyword followed by a dot operator.
S1.idno = 10001
del S1.idno
Here it deletes the attribute id.no.
The built-in attributes found in python are listed below. They can be accessed using the dot notation which is illustrated in the following example.
class Student:
#class attribute
Dept = 'Computer Science'
#instance attribute
def __init__(self,name,age):
self.name=name
self.age=age
print("Student.__dict__:",Student.__dict__)
print("Student.__doc__:",Student.__doc__)
print("Student.__name__:",Student.__name__)
print("Student.__module__:",Student.__module__)
print("Student.__bases__:",Student.__bases__)
Output:
Student.__dict__: {'__module__': '__main__', 'Dept': 'Computer Science', '__init__':, '__dict__': , '__weakref__': , '__doc__': None} Student.__doc__: None Student.__name__: Student Student.__module__: __main__ Student.__bases__: ( ,)
Object-oriented programming supports the use of methods in the class. An instance method can be referred to as a function that is defined inside the class to specify the behaviors of the object. The key point to keep in mind is that always ensure to call the instance method from the instance of that particular class itself. Moreover, the first parameter of an instance method is always the self
as in the .__init__()
method.
Let’s see how to create an instance method by carefully observing the following example. In our Student class, we have two instance methods namely
class Student:
#class attribute
Dept = 'Computer Science'
#instance attribute
def __init__(self,name,age):
self.name=name
self.age=age
#instance Methods
def StudDetails(self):
print('Hi Iam',self.name,'and Iam',self.age,'years old. ')
def StudAct(self, activity):
print(self.name,'is good at',activity)
S1 = Student("Chris", 17)
S2 = Student('Debora',16)
S1.StudDetails() #calling instance method StudDetails()
S2.StudDetails()
S1.StudAct("Football") #calling instance method StudAct()
S2.StudAct('Tennis')
Here in this example, StudDetails()
method is defined to print the name and age of Students. StudAct()
method prints the activity in which the particular student is good at. For instance on calling, S1.StudDetails()
method the control shifts to the function StudDetails defined inside the class Student where it performs the print function. The parameters defined in StudDetails is self which gives the values defined in .__init__()
method. Hence it is possible for us to access the instance attributes .name
and .age
. And finally, the output is printed as Hi Iam Chris and Iam 17 years old.
In the same manner S1.StudAct("Football")
prints the output as Chris is good at Football, where the parameter"Football" is passed to ‘activity’ argument in the method definition.
Output:
Hi Iam Chris and Iam 17 years old. Hi Iam Debora and Iam 16 years old. Chris is good at Football Debora is good at Tennis