Skip to content

Latest commit

 

History

History
355 lines (256 loc) · 7.98 KB

20-object-oriented-programming.md

File metadata and controls

355 lines (256 loc) · 7.98 KB

Python Object-Oriented Programming

Video link: https://youtu.be/pnWINBJ3-yA

In this video, you learned about object-oriented programming along with the help of examples.

Programs in the Video


Python Classes and Objects

Think of a class as a blueprint of a house. It contains all the details about the floors, doors, windows etc. Based on these descriptions we build the house. The actual physical house is the object.

class Student:
    pass

student1 = Student()
student2 = Student()

Here, student1 and student2 are objects of the Student class.

Now, we can start adding different attributes to these object instances.

class Student:
    pass

student1 = Student()
student1.name = "Harry"
student1.marks = 85

print(student1.name)
print(student1.marks)

Output

Harry
85

Let's now see how we can define methods inside a class.

class Student:
    def check_pass_fail(self):
        if self.marks >= 40:
            return True
        else:
            return False

student1 = Student()
student1.name = "Harry"
student1.marks = 85

did_pass = student1.check_pass_fail()
print(did_pass)

Output

True

Here, the check_pass_fail() method is defined inside the Student class.

Now, any object created from the Student class can access this method.

We have called this method without passing any arguments, however, the method definition takes one argument named self.

Whenever we define methods for a class, we need to use self as the first parameter. This self represents the object calling it. In our example, self refers to the student1 object, and self.marks refers to the marks attribute of student1.

Let's try the same for another student object.

class Student:
    def check_pass_fail(self):
        if self.marks >= 40:
            return True
        else:
            return False

student1 = Student()
student1.name = "Harry"
student1.marks = 85

did_pass = student1.check_pass_fail()
print(did_pass)

student2 = Student()
student2.name = "Janet"
student2.marks = 30
did_pass = student2.check_pass_fail()
print(did_pass)

Output

True
False

Note: Using self is just a convention but we highly recommend using self.


The __init__() Method

Adding attributes to the object manually after defining it is not a good practice.

Python offers a much more elegant and compact way of defining attributes right while instantiating the object. For that, we use the init method.

If you are coming from other languages like C++ or Java, the Python __init__() method closely resembles constructors.

class Student:
    
    def __init__(self, name, marks):
        self.name = name
        self.marks = marks
        
    def check_pass_fail(self):
        if self.marks >= 40:
            return True
        else:
            return False

student1 = Student("Harry", 85)
print(student1.name)
print(student1.marks)

Output

Harry
85

When we create an object, this __init__() method is automatically called. We have used Harry and 85 during object creation, these values are passed to name and marks in the __init()__ method.

Remember, the first parameter self represents the object calling it, while the second and third parameter take the two arguments which we used during object creation.

Now, for the student1 object, the name attribute will be Harry and marks will be 85.

Let's try creating one more object.

class Student:
    
    def __init__(self, name, marks):
        self.name = name
        self.marks = marks
        
    def check_pass_fail(self):
        if self.marks >= 40:
            return True
        else:
            return False

student1 = Student("Harry", 85)
print(student1.name)
print(student1.marks)

student2 = Student("Janet", 30)
print(student1.name)
print(student1.marks) 

Output

Harry
85
Janet
30

We get the attributes of student2 as well.

Let's check if they passed or failed the exams using the check_pass_fail() method.

class Student:
    
    def __init__(self, name, marks):
        self.name = name
        self.marks = marks
        
    def check_pass_fail(self):
        if self.marks >= 40:
            return True
        else:
            return False

student1 = Student("Harry", 85)
did_pass = student1.check_pass_fail()
print(did_pass)

student2 = Student("Janet", 30)
did_pass = student2.check_pass_fail()
print(did_pass)

Output

True
False

Example: Add Two Complex Numbers

In this example, we will add two complex numbers manually. Python already handles this by default, but we will create our own Complex class to better understand the concepts of object-oriented programming.

If you do not know, a complex number has real and imaginary parts. When we add two complex numbers, we need to add real and imaginary parts separately.

Let's first create a class that represents complex numbers.

class Complex:
    def __init__(self, real, imag):
        self.real = real
        self.imag = imag

n1 = Complex(5, 6)
n2 = Complex(-4, 2)

Now, let's create a method to add these complex numbers.

class Complex:
    def __init__(self, real, imag):
        self.real = real
        self.imag = imag
        
    def add(self, number):
        real = self.real + number.real
        imag = self.imag + number.imag
        result = Complex(real, imag)
        return result

n1 = Complex(5, 6)
n2 = Complex(-4, 2)
result = n1.add(n2)

The value returned by add() is itself an object of the Complex class.

Let's print the attributes of the result object.

class Complex:
    def __init__(self, real, imag):
        self.real = real
        self.imag = imag
        
    def add(self, number):
        real = self.real + number.real
        imag = self.imag + number.imag
        result = Complex(real, imag)
        return result

n1 = Complex(5, 6)
n2 = Complex(-4, 2)
result = n1.add(n2)

print("real =", result.real)
print("imag =", result.imag)

Output

real = 1
imag = 8

Why object-oriented programming?

Creating objects allows us to organize related data and functionalities together. This helps us to write structured and flexible code.

Now, instead of thinking in terms of individual data and functions, we start thinking in terms of objects and how one object interacts with the other. This helps us to divide a complex problem into smaller sub-problems.

Also, using an object-oriented style of programming makes our code reusable because we can define multiple objects with similar attributes and functionalities from a single Class.


Programming Task

Task

  • Create a class named Triangle.
  • Create an object from it. The object will have three attributes named a, b and c that represent the sides of the triangle.
  • The Triangle class will have two methods:
    • The __init__() method to initialize the sides
    • A Method to calculate the perimeter of the triangle from its sides
  • The perimeter of the triangle should be printed from outside the class

Here's the barebone for this program:

class Triangle:
    def __init__(self, a, b, c):
        # write code here
        pass
    
    # write code here
    
t1 = Triangle(3, 4, 5)
# write code here

Solution

class Triangle:
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c
    
    def get_perimeter(self):
        perimeter = self.a + self.b + self.c
        return perimeter
    
t1 = Triangle(3, 4, 5)

perimeter = t1.get_perimeter()
print("The perimeter of the t1 triangle is", perimeter)

Output

The perimeter of the t1 triangle is 12