0% found this document useful (0 votes)
19 views

Object oriented programming_2

The document discusses key concepts of Object-Oriented Programming (OOP) in Python, focusing on polymorphism, method overriding, and operator overloading. It explains how to implement method overriding using the super() method and how to overload operators by defining special functions. Additionally, it covers dynamic attributes in Python and provides examples to illustrate these concepts.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
19 views

Object oriented programming_2

The document discusses key concepts of Object-Oriented Programming (OOP) in Python, focusing on polymorphism, method overriding, and operator overloading. It explains how to implement method overriding using the super() method and how to overload operators by defining special functions. Additionally, it covers dynamic attributes in Python and provides examples to illustrate these concepts.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 16

Object oriented programming

(OOP)
Polymorphism
• Method Overloading : Not possible in python
since in python every thing is an object.
• Method Overriding : Possible.
The super( ) method:
• super().init() # call super class constructor
• super().init(arguments) # call super class
constructor and pass arguments
• super().method() # call super class method
Method overriding is a feature of Object-oriented programming that enables you to
change the behavior of inherited methods as per our specific needs. Here, the method
in a derived class has the same name and the same number of arguments as the base
class.
Base class's method is called overridden method and the derived class method is
called overriding method.
#Python program to implement method overriding
class Animal:
def sound(self):
print('Animal makes sound.')

class Dog(Animal):
def sound(self):
print('Dog barks.')

d = Dog()
d.sound()
How to call base class overridden method from derived class?
There are two ways of calling base class overridden method-
•Using class name
•Using super()
Using class name to call base class method: Use class name followed by dot and then
function name that you want to call. Syntax will be ClassName.OverriddenMethod()
#Python Program to call base class overridden method using class name
class Animal:
def sound(self):
print('Animal makes sound.')

class Dog(Animal):
def sound(self):
Animal.sound(self)
print('Dog barks.')

d = Dog()
d.sound()
Using super() to call base class method: Use super() followed by dot and then function
name that you want to call. Syntax will be super().OverriddenMethod()
#Python Program to call base class overridden method using super()
class Animal:
def sound(self):
print('Animal makes sound.')

class Dog(Animal):
def sound(self):
super().sound()
print('Dog barks.')

d = Dog()
d.sound()
• Python Operator Overloading
Python operators work for built-in classes. But the
same operator behaves differently with different
types. For example, the + operator will perform
arithmetic addition on two numbers, merge two lists,
or concatenate two strings.
This feature in Python that allows the same operator to
have different meaning according to the context is
called operator overloading.
class Point:
def __init__(self, x=0, y=0):
self.x = x
self.y = y

p1 = Point(1, 2)
p2 = Point(2, 3)
print(p1+p2)

Output:
Traceback (most recent call last):
File "<string>", line 9, in <module>
print(p1+p2)
TypeError: unsupported operand type(s) for +: 'Point' and 'Point'
Python Special Functions
Class functions that begin with double underscore __ are called special
functions in Python.

These functions are not the typical functions that we define for a class. The
__init__() function we defined is one of them. It gets called every time we
create a new object of that class. There are numerous other special functions
in Python.
Using special functions, we can make our class compatible with built-in
functions.
>>> p1 = Point(2,3)
>>> print(p1)
<__main__.Point object at 0x00000000031F8CC0>
Suppose we want the print() function to print the coordinates of the Point
object instead of what we got. We can define a __str__() method in our class
that controls how the object gets printed. Let's look at how we can achieve
this:
class Point:
def __init__(self, x = 0, y = 0):
self.x = x
self.y = y

def __str__(self):
return "({0},{1})".format(self.x,self.y)

p1 = Point(2, 3)
print(p1)
Output:
(2, 3)
Overloading the + Operator: To overload the + operator, we will need to
implement __add__() function in the class. With great power comes great
responsibility. We can do whatever we like, inside this function. But it is more
sensible to return a Point object of the coordinate sum.

class Point:
def __init__(self, x=0, y=0):
self.x = x
self.y = y

def __str__(self):
return "({0},{1})".format(self.x, self.y)

def __add__(self, other):


x = self.x + other.x
y = self.y + other.y
return Point(x, y) Contd.
p1 = Point(1, 2)
p2 = Point(2, 3)
print(p1+p2)
Output:
(3,5)

What actually happens is that, when you use p1 + p2, Python calls
p1.__add__(p2) which in turn is Point.__add__(p1,p2). After this, the
addition operation is carried out the way we specified.
Similarly, we can overload other operators as well. The special function that
we need to implement is tabulated below.
Operator Expression Internally

Addition p1 + p2 p1.__add__(p2)

Subtraction p1 - p2 p1.__sub__(p2)

Multiplication p1 * p2 p1.__mul__(p2)

Power p1 ** p2 p1.__pow__(p2)

Division p1 / p2 p1.__truediv__(p2)

Floor Division p1 // p2 p1.__floordiv__(p2)

Remainder (modulo) p1 % p2 p1.__mod__(p2)

Bitwise Left Shift p1 << p2 p1.__lshift__(p2)

Bitwise Right Shift p1 >> p2 p1.__rshift__(p2)

Bitwise AND p1 & p2 p1.__and__(p2)

Bitwise OR p1 | p2 p1.__or__(p2)

Bitwise XOR p1 ^ p2 p1.__xor__(p2)

Bitwise NOT ~p1 p1.__invert__()


# overloading the less than operator
class Point:
def __init__(self, x=0, y=0):
self.x = x
self.y = y

def __str__(self):
return "({0},{1})".format(self.x, self.y)

def __lt__(self, other):


self_mag = (self.x ** 2) + (self.y ** 2)
other_mag = (other.x ** 2) + (other.y ** 2)
return self_mag < other_mag

p1 = Point(1,1)
p2 = Point(-2,-3)
p3 = Point(1,-1)

# use less than


print(p1<p2) #True
print(p2<p3) #False
print(p1<p3) #False
Operator Expression Internally

Less than p1 < p2 p1.__lt__(p2)

Less than or equal


p1 <= p2 p1.__le__(p2)
to

Equal to p1 == p2 p1.__eq__(p2)

Not equal to p1 != p2 p1.__ne__(p2)

Greater than p1 > p2 p1.__gt__(p2)

Greater than or
p1 >= p2 p1.__ge__(p2)
equal to
Dynamic attributes in Python are terminologies for attributes that are defined at runtime,
after creating the objects or instances. In Python we call all functions, methods also as an
object. So you can define a dynamic instance attribute for nearly anything in Python.
Consider the below example for better understanding about the topic.

class Demo:
None

def value():
return 10

g = Demo()

# Dynamic attribute of a class object


g.d1 = value

# Dynamic attribute of a function


value.d1 = "Python"

print(value.d1)
print(g.d1() == value())
class GFG:
employee = True

# Driver Code
e1 = GFG()
e2 = GFG()

e1.employee = False
e2.name = "Nikhil"

print(e1.employee)
print(e2.employee)
print(e2.name)

# this will raise an error as name is a dynamic attribute created only for the
e2 object
print(e1.name)

You might also like