Module 5 - OOP
Module 5 - OOP
A real instance of a class is called an object and creating the new object is called instantiation.
Objects can also have functionality by using functions that belong to a class. Such functions are
called methods of the class. This terminology is important because it helps us to differentiate
between functions and variables which are independent and those which belong to a class or
object. Collectively, the fields and methods can be referred to as the attributes of that class. Let
us take the example of the class Mobile_phone which is represented in the block diagram
below:
Python Class
A class is a collection of objects. A class contains the blueprints or the prototype from which the
objects are being created. It is a logical entity that contains some attributes and methods.
# Python3 program to
# demonstrate defining
# a class
class Dog:
pass
# Python program to
# demonstrate defining
# a class
class Dog:
pass
Python Objects
The object is an entity that has a state and behavior associated with it. It may be any real-world
object like a mouse, keyboard, chair, table, pen, etc. Integers, strings, floating-point numbers,
even arrays, and dictionaries, are all objects. More specifically, any single integer or any single
string is an object. The number 12 is an object, the string “Hello, world” is an object, a list is an
object that can hold other objects, and so on. You’ve been using objects all along and may not
even realize it.
An object consists of:
obj = Dog()
class Dog:
# class attribute
attr1 = "mammal"
# Instance attribute
def __init__(self, name):
self.name = name
# Driver code
# Object instantiation
Output
Rodger is a mammal
Tommy is also a mammal
My name is Rodger
My name is Tommy
Creating Classes and objects with methods
Here, The Dog class is defined with two attributes:
attr1 is a class attribute set to the value “mammal”. Class attributes are shared by all
instances of the class.
__init__ is a special method (constructor) that initializes an instance of the Dog class. It
takes two parameters: self (referring to the instance being created) and name (representing
the name of the dog). The name parameter is used to assign a name attribute to each
instance of Dog.
The speak method is defined within the Dog class. This method prints a string that includes
the name of the dog instance.
The driver code starts by creating two instances of the Dog class: Rodger and Tommy. The
__init__ method is called for each instance to initialize their name attributes with the provided
names. The speak method is called in both instances (Rodger.speak() and Tommy.speak()),
causing each dog to print a statement with its name.
class Dog:
# class attribute
attr1 = "mammal"
# Instance attribute
def __init__(self, name):
self.name = name
def speak(self):
print("My name is {}".format(self.name))
Output
My name is Rodger
My name is Tommy
Python Inheritance
Inheritance is the capability of one class to derive or inherit the properties from another class.
The class that derives properties is called the derived class or child class and the class from
which the properties are being derived is called the base class or parent class. The benefits of
inheritance are:
It represents real-world relationships well.
It provides the reusability of a code. We don’t have to write the same code again and again.
Also, it allows us to add more features to a class without modifying it.
It is transitive in nature, which means that if class B inherits from another class A, then all
the subclasses of B would automatically inherit from class A.
Types of Inheritance
Single Inheritance: Single-level inheritance enables a derived class to inherit characteristics
from a single-parent class.
Multilevel Inheritance: Multi-level inheritance enables a derived class to inherit properties
from an immediate parent class which in turn inherits properties from his parent class.
Hierarchical Inheritance: Hierarchical-level inheritance enables more than one derived
class to inherit properties from a parent class.
Multiple Inheritances: Multiple-level inheritance enables one derived class to inherit
properties from more than one base class.
Inheritance in Python
In the above article, we have created two classes i.e. Person (parent class) and Employee (Child
Class). The Employee class inherits from the Person class. We can use the methods of the
person class through the employee class as seen in the display function in the above code. A
child class can also modify the behavior of the parent class as seen through the details()
method.
def display(self):
print(self.name)
print(self.idnumber)
def details(self):
print("My name is {}".format(self.name))
print("IdNumber: {}".format(self.idnumber))
# child class
class Employee(Person):
def __init__(self, name, idnumber, salary, post):
self.salary = salary
self.post = post
def details(self):
print("My name is {}".format(self.name))
print("IdNumber: {}".format(self.idnumber))
print("Post: {}".format(self.post))
Output
Rahul
886012
My name is Rahul
class Bird:
def intro(self):
print("There are many types of birds.")
def flight(self):
print("Most of the birds can fly but some cannot.")
class sparrow(Bird):
def flight(self):
print("Sparrows can fly.")
class ostrich(Bird):
def flight(self):
print("Ostriches cannot fly.")
obj_bird = Bird()
obj_spr = sparrow()
obj_ost = ostrich()
obj_bird.intro()
obj_bird.flight()
obj_spr.intro()
obj_spr.flight()
obj_ost.intro()
obj_ost.flight()
Output
There are many types of birds.
Most of the birds can fly but some cannot.
Encapsulation in Python
In the above example, we have created the c variable as the private attribute. We cannot even
access this attribute directly and can’t even change its value.
# Python program to
# demonstrate private members
# Calling constructor of
# Base class
Base.__init__(self)
print("Calling private member of base class: ")
print(self.__c)
Output
GeeksforGeeks
# Python program to
# demonstrate protected members
# Protected member
self._a = 2
# Calling constructor of
# Base class
Base.__init__(self)
print("Calling protected member of base class: ",
self._a)
obj1 = Derived()
obj2 = Base()
Output:
Calling protected member of base class: 2
Calling modified protected member outside class: 3
Accessing protected member of obj1: 3
Accessing protected member of obj2: 2
# Python program to
# demonstrate private members
class Base:
def __init__(self):
self.a = "GeeksforGeeks"
self.__c = "GeeksforGeeks"
# Calling constructor of
# Base class
Base.__init__(self)
print("Calling private member of base class: ")
print(self.__c)
# Driver code
obj1 = Base()
print(obj1.a)
Output:
GeeksforGeeks
Data Abstraction
It hides unnecessary code details from the user. Also, when we do not want to give out
sensitive parts of our code implementation and this is where data abstraction came.
Data Abstraction in Python can be achieved by creating abstract classes.
Data hiding
In Python, we use double underscore (Or __) before the attributes name and those
attributes will not be directly visible outside.
Python
class MyClass:
# Driver code
myObject = MyClass()
myObject.add(2)
myObject.add(5)
Output :
2
7
# Driver code
myObject = MyClass()
print(myObject._MyClass__hiddenVariable)
Output :
10
Private methods are accessible outside their class, just not easily accessible. Nothing in
Python is truly private; internally, the names of private methods and attributes are mangled
and unmangled on the fly to make them seem inaccessible by their given names [See this for
source ].
Printing Objects
Printing objects give us information about objects we are working with. In C++, we can do
this by adding a friend ostream& operator << (ostream&, const Foobar&) method for the
class. In Java, we use toString() method.
In python, this can be achieved by using __repr__ or __str__ methods.
Python
class Test:
def __init__(self, a, b):
self.a = a
self.b = b
def __repr__(self):
return "Test a:%s b:%s" % (self.a, self.b)
def __str__(self):
# Driver Code
t = Test(1234, 5678)
print(t) # This calls __str__()
print([t]) # This calls __repr__()
Output :
From str method of Test: a is 1234,b is 5678
[Test a:1234 b:5678]
Important Points about Printing:
If no __str__ method is defined, print t (or print str(t)) uses __repr__.
Python
class Test:
def __init__(self, a, b):
self.a = a
self.b = b
def __repr__(self):
return "Test a:%s b:%s" % (self.a, self.b)
# Driver Code
t = Test(1234, 5678)
print(t)
Output :
Test a:1234 b:5678
If no __repr__ method is defined then the default is used.
Python
class Test:
def __init__(self, a, b):
self.a = a
self.b = b
# Driver Code
t = Test(1234, 5678)
print(t)
Output :
<__main__.Test instance at 0x7fa079da6710>