#polymorphism >> poly means many and morphism means forms/states
#refers to an object taking several forms depending on the
methods/data
len("Ajay")
len([1, 2, 3, 4, 5])
len((1, 2))
def func(a, b):
return a+b
func(2, 3) #same + adding two numbers
func("pw", "skills") #same +, combining two strings
'pwskills'
func([1, 2, 3], [4, 5, 6]) #the list concatenation
[1, 2, 3, 4, 5, 6]
#observation>> func is taking different forms with respect to
different data passed
class teacher_lecture:
def lec_info(self):
print("This is lec info with teacher perspective")
class student_lecture:
def lec_info(self):
print("This is lec info with student perspective")
obj1 = teacher_lecture()
obj2 = student_lecture()
class_obj = [obj1, obj2]
def parcer(class_obj):
for i in class_obj:
i.lec_info() #at this point, lec_info is taking two forms wrt
techer and students
parcer(class_obj)
This is lec info with teacher perspective
This is lec info with student perspective
#Polymorphism in OOPS takes places in two ways:
#Method overloading >> python doesnt support true method overloading
#Method overriding
#method overloading
class Student:
def student(self):
print("Wecome to pwskills class")
def student(self, name = ""):
print("Wecome to pwskills class", name)
def student(self, name = "", course = ""):
print("Wecome to pwskills class", name, course)
stud = Student()
stud.student()
Wecome to pwskills class
stud.student("Ajay")
Wecome to pwskills class Ajay
stud.student("Ajay", "DS")
Wecome to pwskills class Ajay DS
#method overloading >> student method is taking different forms, the
last methods overloads the previous ones in the same class
class Student:
def student(self, name = "", course = ""):
print("Wecome to pwskills class", name, course)
stud = Student()
stud.student()
Wecome to pwskills class
stud.student("Ajay")
Wecome to pwskills class Ajay
stud.student("Ajay", "DS")
Wecome to pwskills class Ajay DS
#method overloading happens in the same class
#method overriding >> method in parent class and child class with same
signature, the child class method will be executed
class Animal:
def sound(self):
print("Animal Sound")
class Cat(Animal):
def sound(self):
print("cat meows")
anm = Animal()
anm.sound() #Animal class
Animal Sound
cat = Cat()
cat.sound() #cat class
cat meows
#Encapsulation>> means hiding something
#bundling of data and methods of a class
#access modifier>>public, protected, private
#public>>accessible from anywhere from outside/inside of class
class Student:
def __init__(self, name, degree):
self.name = name
self.degree = degree
stud1 = Student("Ram", "Masters")
stud1.name
'Ram'
stud1.degree
'Masters'
stud2 = Student("Sam", "Bach")
stud2.degree
'Bach'
stud2.degree = "Phd"
stud2.degree
'Phd'
#accessing the public data member inside the other method of same
class
class Student:
def __init__(self, name, degree):
self.name = name
self.degree = degree
def show(self):
#accessing the public data member
print("name", self.name, 'degree', self.degree)
aj = Student("Ajay", "Masters")
aj.show()
name Ajay degree Masters
aj.name
'Ajay'
aj.degree
'Masters'
#private >> the data and method is only accessible within its class,
use __ to make private
class Student:
def __init__(self, name, degree):
self.name = name
self.__degree = degree #private data
def show(self):
#accessing the private data member
print("name", self.name, 'degree', self.__degree)
aj = Student("Ajay", "Masters")
aj.name
'Ajay'
aj.show()
name Ajay degree Masters
aj.degree #it will throw an error as degree is now private data
----------------------------------------------------------------------
-----
AttributeError Traceback (most recent call
last)
Cell In[67], line 1
----> 1 aj.degree #it will throw an error as degree is now private
data
AttributeError: 'Student' object has no attribute 'degree'
aj.__degree #it will throw an error as degree is now private data
----------------------------------------------------------------------
-----
AttributeError Traceback (most recent call
last)
Cell In[68], line 1
----> 1 aj.__degree #it will throw an error as degree is now private
data
AttributeError: 'Student' object has no attribute '__degree'
aj._Student__degree #say you want to access the private variable using
class name
'Masters'
#a method private
class Student:
def __init__(self, name, degree):
self.name = name
self.__degree = degree #private data
def show(self):
#accessing the private data member
print("name", self.name, 'degree', self.__degree)
def __private_method(self):
print("This is a private method")
obj1 = Student("Ajay", "Masters")
obj1.private_method() #throw an error
----------------------------------------------------------------------
-----
AttributeError Traceback (most recent call
last)
Cell In[72], line 1
----> 1 obj1.private_method()
AttributeError: 'Student' object has no attribute 'private_method'
obj1.__private_method() #throw an error
----------------------------------------------------------------------
-----
AttributeError Traceback (most recent call
last)
Cell In[73], line 1
----> 1 obj1.__private_method() #throw an error
AttributeError: 'Student' object has no attribute '__private_method'
obj1._Student__private_method() #accesing private method using class
name
This is a private method
#way to provide an option to see the private method>> a wrapper
class Student:
def __init__(self, name, degree):
self.name = name
self.__degree = degree #private data
def show(self):
#accessing the private data member
print("name", self.name, 'degree', self.__degree)
def __private_method(self):
print("This is a private method")
def access_private_method(self):
self.__private_method()
obj1 = Student("AJ", "Masters")
obj1.access_private_method()
This is a private method
#another use case of modifying the private variable and accessing it
class Car:
def __init__(self, year, make, speed, model):
self.__year = year
self.__make = make
self.__speed = speed
self.__model = model
c1 = Car("1995", "Maruti", "80", "Brezza")
c1.year #since all variables are private, it will throw an error
----------------------------------------------------------------------
-----
AttributeError Traceback (most recent call
last)
Cell In[79], line 2
1 c1 = Car("1995", "Maruti", "80", "Brezza")
----> 2 c1.year
AttributeError: 'Car' object has no attribute 'year'
class Car:
def __init__(self, year, make, speed, model):
self.__year = year
self.__make = make
self.__speed = speed
self.__model = model
def set_speed(self, speed):
self.__speed = 0 if speed < 0 else speed
def get_speed(self):
return self.__speed
c1 = Car("1995", "Maruti", "80", "Brezza")
c1.get_speed()
'80'
c1.set_speed(-1000)
c1.get_speed()
c1.set_speed(100)
c1.get_speed()
100
#anaother use case
class Bank: #either you deposit or withdraw
def __init__(self, balance):
self.__balance = balance
def deposit(self, amount): #amount is new deposition
self.__balance = self.__balance + amount
def withdraw(self, amount):
if self.__balance >= amount:
self.__balance = self.__balance - amount
return True
else:
return False
def get_balance(self):
return self.__balance
acc1 = Bank(1000)
acc1.get_balance()
1000
acc1.deposit(500)
acc1.get_balance()
1500
acc1.withdraw(100)
True
acc1.get_balance()
1400
acc1.withdraw(1500)
False
#protected>> within the class and its subclass, protected member can
be access, (_)
class College:
def __init__(self):
self._college_name = "PWSkills"
class Student(College):
def __init__(self, name):
self.name = name
College.__init__(self) #accesing variable of base
class>>classname__init__(self)
def show(self):
print("name", self.name, "college", self._college_name)
#directly call the base class variable using "_"
stud = Student("Ajay")
stud.name
'Ajay'
stud.show()
name Ajay college PWSkills
coll = College()
coll._college_name #accessing the protected variable
'PWSkills'
#anothe rway to access the data of base class using super()