Nowadays the modern software development resides around objects and its oriented programming for a good reason. As it gives a lot of benefits over the old paradigm of procedural programming.
- Python is an object oriented programming language
 - Object orient programming is a way to design the program using classes and objects.
 - The main concepts of OOPs is to bind the data and the functions that work on the data together as a single unit os that no other part of the code can access this data
 - The four concepts that contructs the OOP are data abstraction, polymorphism, encapsulation and inheritance
 
Main concepts of OOP
Class
- Class consists of a collection of objects
 - Classes are known as the blueprint of objects
 - Classes have there own attributes and methods that has the accessibility only by the objects of that class
 - We can initialize the attributes of a Class using init method
 
class Mountblue:
    def __init__(self, name, company):
        self.name = name
        self.company = company
    def some_method_to_work(some arguments):
        # Statements to execute
        # return statements
Object
- Objects are the instance of a class
 - Object are just like real world entities like a car, boy, girl, etc
 - An object consists of methods and attributes
 - Object of a class consist of self parameter which represents the attributes of its class.
 - We can use any parameters in any methods belong to the same class.
 
class Car:
    def __init__(self, brand, model, color):
        self.brand = brand
        self.model = model
        self.color = color
    def show_props(self):
        print(self.brand, self.model)
        print(self.color)
s = Car("Tata", "Nano", "Blue")
s.show_props()
## output: 
Tata Nano
Blue
Data Abstraction
- Data Abstraction or data hiding is to avoid details of an object which are not used in the current task
 - For example, if we are driving a car, we do not need to know the mechanism of how the car works when we push gear, acceleration or brakes.
 - For Data hiding: We use double underscore("__") before the attributes names and those attributes will not be directly visible outside.
 
class MyClass:
    __thisvariablehidden = 0
    def adder(self, increment):
    self.__thisvariablehidden += increment
    print(self.__thisvariablehidden)
object1 = MyClass()
object1.add(200)
object1.add(72)
print(object1.__thisvariablehidden)
# output: 200
#          72
error:
MyClass instance has 
no attribute '__thisvariablehidden'
Encapsulation
- OOP allows us to encapsulate data and behaviour within objects.
 - This means that we can hide implementation details and only the interface is visible for the other parts of the program
 - It helps us for code maintainability and updation the code over time
 - Protected members(single underscore"_") are those classes which cannot be accessed outside the class but can be accessed from within the class
 - Private members(double underscore"__") are the class members that cannot be accessed outside the class as well as inside of any base class. Completely private protected file
 
class Account:
    def __init__(self, balance):
        self.__balance = balance # private attribute
    def deposit(self, amount):
        self.__balance += amount
    def get_balance(self):
        return self.__balance
# The __balance attribute is marked as private by using double underscore
# By using this the balance is secured 
a = BankAccount(50)
a.deposit(50)
print(a.get_balance())
# 100
Polymorphism
- Polymorphism means one type having many forms
 - It allows us to write code that can work with objects of different classes, as long as they have common interface
 - With polymorphism we can can the code more flexible and reusable
 
def add(x, y, z = 0):
    return z + y + z
print(add(4, 5))
print(add(4, 5, 6))
# output : 9
#          15
Method Overriding
- It allows a subclass or child class to provide a specific kind of implementation of a method that is already provided by one of its super-classes or parent classes.
 - When a method in a subclass has the same name, same parameters or signature and same return type as a method in its super-class, then the method in the subclass is said to override the method in the super-class.
 
class Parent():
    def __init__(self):
        self.value = "Inside Parent"
    def show(self):
        print(self.value)
class Child(Parent):
    def __init__(self):
        self.value = "Inside Child"
    def show(self):
        print(self.value)
obj1 = Parent()
obj2 = Child()
obj1.show()
obj2.show()
# Output: Inside Parent
#         Inside Child  
Method Overloading
- Two or more methods have the same name but different numbers of parameters or different types of parameters, or both.
 - The problem with method overloading in python is that we may overload the methods but can only use the latest defined method.
 
def product(a, b):
    d = a * b
    print(d)
def product(a, b, c):
    d = a * b * c
    print(d)
product(3, 4, 2)
# output : 24 
Inheritance
- Inheritance is the capability of one class to derive or inherit the properties from parent class.
 - This can be useful when we have several classes that share common properties or behavior
 - It provides reusability of a code and allows us to add more features to a class without modifying it.
 
Types of Inheritance
1. Single Inheritance
- New class is called the derived class or subclass, and the existing class is called the base class or superclass.
 - The derived class inherits al the properties of the base class
 
class Animal:
    def __init__(self, name, sound):
        self.name = name
        self.sound = sound
    def make_sound(self):
        print(f"{self.name} says {self.sound}!")
class Dog(Animal):
    def __init__(self, name):
        super().__init__(name, "Woof")
dog = Dog("Tommy")
dog.make_sound()
# output : "Tommy says Woof!"
2. Multi-level Inheritance
- In this inheritance a derived class is created based on another derived class, which is based on a base class.
 
class Animal:
    def __init__(self, name, sound):
        self.name = name
        self.sound = sound
    def make_sound(self):
        print(f"{self.name} says {self.sound}!")4
class DomesticAnimal(Animal):
    def __init__(self, name, sound, breed):
        super().__init__(name, sound)
        self.breed = breed
    def show_breed(self):
        print(f"{self.name} is a {self.breed}.")
class Dog(DomesticAnimal):
    def __init__(self, name, breed):
        super().__init__(name, 'Woof', breed)
dog = Dog("Tommy", "German Spitz")
dog.make_sound()
# output : "Tommy says Woof!"
dog.show_breed()
# output : "Tommy is a German Spitz"
    
Top comments (0)