Object-Oriented Programming is a fundamental programming paradigm based on the concepts of objects and classes that can perform certain operations through their methods. We'll get into more details about OOP in this notebook.
Note: For this notebook, one should have some understanding of objects and classes.
Python Classes
A class is more or less a blueprint of an object. A class defines all the attributes and methods a certain object can attain. For example, a class for a student could contain attributes such as name, date of birth, phone number etc. and also contain methods which could perform any desired operations on these attributes.
An important building block of the class is the class' constructor (i.e the __init__ method). This method is the default method called upon instantiation (creating an instance/object of that class) and is usually where we'll define our attributes..
Let us understand all the above through an example.
class Student():
def __init__(self, name):
self.name = name
Instantiation of a new Python object ...
x = Student("Mark")
print(x)
# Printing the type of the object to show which class it belongs to
print(type(x))
# Retrieving the attribute "name" from the object
print(x.name)
Python Objects
An Object (Instance) is an instantiation of a class. As explained earlier, classes are blueprints that we can use to create objects/instances. The example shown above of the student class explains how to create a class and instantiate an object. Let us add more attributes to that class and test it's functionality.
import datetime
class Student():
def __init__(self, name, dob, number):
self.name = name
self.birth_date = dob
self.phone_number = number
x = Student("Mark", "07/25/94", "123456789")
print(x)
print(type(x))
print("Student Name: ", x.name)
print("Student Birth Date: ", x.birth_date)
print("Student Phone Number: ", x.phone_number)
Python Methods
Methods are special types of functions. There is a difference between functions and methods and that is due to the fact that methods are only specific to the classes they belong to whereas functions have more of a global scope. Let us put all this into action and create a method in our student class to calculate the student's age from his/her date of birth.
class Student():
def __init__(self, name, dob, number):
self.name = name
self.birth_date = dob
self.phone_number = number
def age_calculator(self):
current_date = datetime.datetime.now().date()
student_birthdate = datetime.datetime.strptime(self.birth_date, "%m/%d/%y").date()
delta = current_date - student_birthdate
age = int(delta.days/365)
return age
I have used Python datetime package in above code. To learn more about Python datetime checkout here.
x = Student("Mark", "07/25/94", "123456789")
print(x)
print(type(x))
print("Student Name: ", x.name)
print("Student Birth Date: ", x.birth_date)
print("Student Phone Number: ", x.phone_number)
print("Student Age: ", x.age_calculator())
Voila! Now you have an idea about the building blocks of OOP in Python. Now let us discuss the Object Oriented Programming advantages.
Inheritance In Python
One of the main reasons developers tend to use OOP paradigm is inheritance. To understand inheritance, Let us build up on our previous student example and extend it for university students. Now there can be different type of students in a university. For example:
- Undergraduate Students
- Postgraduate Students
- Exchange Students (Undergraduate and Postgraduate)
For above cases, we can write a class for each type, however, this will make our code very messy and unreadable. Instead, the inheritance feature that OOP provides will help us create abstract parent class from which children classes could inherit the common features. So what are the common attributes among all the students type defined above?
- name
- date of birth
- phone number
- address
Now, Let us write a basic student "parent" class that will include the above basic attributes and then later we will write the child classes for every student type.
class Student():
def __init__(self, name, dob, number, address):
self.name = name
self.birth_date = dob
self.number = number
self.address = address
Now that we have created the parent abstract class, let us see how children subclasses can inherit this information and also can have their own unique attributes.
class Undergraduate(Student):
def __init__(self, name, dob, number, address, sat_score):
Student.__init__(self, name, dob, number, address)
self.sat_score = sat_score
class Postgraduate(Student):
def __init__(self, name, dob, number, address, bachelors_gpa):
Student.__init__(self, name, dob, number, address)
self.bachelors_gpa = bachelors_gpa
x = Undergraduate("Mark", "07/21/94", "123456789", "12 Hollywood St.", "1450")
y = Postgraduate("Sam", "04/15/89", "987654321", "75 Hollywood St.", "3.50")
print(type(x))
print("Student Name: ", x.name)
print("Student Birth Date: ", x.birth_date)
print("Student Phone Number: ", x.number)
print("Student's Address: ", x.address)
print("Student's SAT Score: ", x.sat_score)
print('-----------------------------------')
print(type(y))
print("Student Name: ", y.name)
print("Student Birth Date: ", y.birth_date)
print("Student Phone Number: ", y.number)
print("Student's Address: ", y.address)
print("Student's Bachelor's GPA: ", y.bachelors_gpa)
Without inheritance, your code would have looked something like this ...
class Undergraduate():
def __init__(self, name, dob, number, address, sat_score):
self.name = name
self.birth_date = dob
self.number = number
self.address = address
self.sat_score = sat_score
class Postgraduate():
def __init__(self, name, dob, number, address, bachelors_gpa):
self.name = name
self.birth_date = dob
self.number = number
self.address = address
self.bachelors_gpa = bachelors_gpa
Now imagine what would have happened if you had 10 or more of the these above classes and not just two.
Polymorphism in Python
Polymorphism is the ability to use a common interface for multiple data types or forms. In examples below, we will observe how the same method can have different forms or outputs depending on their class. Let us take the classes from our previous example and add method "highest_degree" that can take different forms.
class Student():
def __init__(self, name, dob, number, address):
self.name = name
self.birth_date = dob
self.number = number
self.address = address
def highest_degree(self):
print("Abstract Base Method")
class Undergraduate(Student):
def __init__(self, name, dob, number, address, sat_score):
Student.__init__(self, name, dob, number, address)
self.sat_score = sat_score
def highest_degree(self):
return "Highest Degree is High Level Education."
class Postgraduate(Student):
def __init__(self, name, dob, number, address, bachelors_gpa):
Student.__init__(self, name, dob, number, address)
self.bachelors_gpa = bachelors_gpa
def highest_degree(self):
return "Highest Degree is a bachelor's degree."
x = Undergraduate("Mark", "07/21/94", "123456789", "12 Hollywood St.", "1450")
y = Postgraduate("Sam", "04/15/89", "987654321", "75 Hollywood St.", "3.50")
print(x.highest_degree())
print(y.highest_degree())
As you can see, even though we used the same method call, the output was different for each and every class due to the fact that we have overridden the method called highest_degree
and made it custom to each and every class to demonstrate the concept that is polymorphism.
One side note here, In python, we denote the private attributes using the uderscore _
.
class Car():
def __init__(self, price):
self.__price = price
def set_price(self, price):
self.__price = price
def selling_price(self):
return self.__price
x = Car(1500)
print("Initial price: ", x.selling_price())
Let us try to change the price by accessing the private attribute and see if it works.
x.__price = 2000
print("Price change attempt: ", x.selling_price())
As we can see, it did'nt work. Now let us try changing the price using the setter function set_price
that we created for this purpose.
x.set_price(2000)
print("New price: ", x.selling_price())
Note that you can also make an attribute private and not create a setter method for it that would make the attribute "price" unchangeable.
Ok, So far so good. We are now approaching the end of this introductory tutorial on Object oriented Programming. Let us end this tutorial by summarizing the Uses and advantages of OOP.
from Planet Python
via read more
No comments:
Post a Comment