Object Oriented Programming
Published: 2023-05-11 06:55:14

## Introduction 
Python is an object-oriented language that fully supports OOP concepts.Object-oriented programming (OOP) is a design principle which focuses on the concept of objects, which are instances of classes.

## Objects :-
In Python, everything is an object. A object is a instance of a class, which is a blueprint or a template for creating objects. Objects in Python have attributes and methods.
example :-
```
class  Rectangle: 
	def  __init__(self, length, width):
		self.length = length
		self.width = width
	def  area(self):
		return self.length * self.width
```
Creating a object of rectangle class name rect and passing values in it.
```
rect = Rectangle(10, 5)
print(rect.area())
50
```

## Classes :-
In Python, a class is a blueprint or a template for creating objects. A class defines a set of attributes and methods that describe the behavior of the objects created from it.
For making a  **Class**  in Python. We use  **Class**  keyword.Here is a example:-
```
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def introduction(self):
        print("Hi, my name is " + self.name + " and I'm " + str(self.age) + " years old.")
```
Creating an object of Person named class and passing values  in it.
```
p = Person("Alice", 25)
```
Calling the function.
```
p.introduce()
# output:
Hi, my name is Alice and I'm 25 years old.
```
## Inheritance :-
It is a concept of creating a new class from an existing class, inheriting all the attributes and methods of the parent class. In Python, we achieved this through the use of the `super()` function and `isinstance()` function.
 ### 1.  Single inheritance :-
It is the most common type of inheritance, where a subclass inherits from a single parent class. The subclass inherits all the attributes and methods of the parent class.
Here is a example :- In this we are creating a `Animal`class and make function inside it named as`speak`
```
class  Animal:

	def  __init__(self, name):
		self.name = name
		
	def  speak(self):
		print("")
```
Here we are creating a class named as `Dog` which is inherited by `Animal` class.
```
		
class  Dog(Animal):
	def  speak(self):
		print("Woof!")
		
dog = Dog("Rover")
print(dog.name) # output : "Rover"
dog.speak() # output: "Woof!"
```
###  2.Multiple inheritance :-
In this a subclass inherits from multiple parent classes. In this case, the subclass inherits all the attributes and methods of each parent class.
Here is example :- In this we are creating a class named `Base1` and inside it we are creating a function named as `method1`.
```
class  Base1:
	def  method1(self):
		print("Base1 method")
```
Here we are creating a second class named as `Base2` and inside it we are creating a function named as `method2`
```		
class  Base2:
	def  method2(self):
		print("Base2 method")
```
Here we are creating a classnamed as `Derived` which is inheriting the class named as `Base1`,`Base2`.  
```
class  Derived(Base1, Base2):
	pass
```
Here we are creating a object of `Drived` class and callng the function of `Base1` class and `Base2` class.
```
d = Derived()	
d.method1() # Outputs "Base1 method"
d.method2() # Outputs "Base2 method"
```
### 3.Multi-level inheritance :-
In this a subclass inherits from a parent class, which in turn inherits from another parent class. In this case, the subclass inherits all the attributes and methods of both parent classes in the hierarchy.
Here is a example :-
Here we are creating a class named as `Animal` and passing a value in its constructor.
```
class  Animal:
	def  __init__(self, name):
		self.name = name 
```
Here we are creating a class named as `Mammal` which is inheriting the properties of `Animal` class and inside this we are making a function named as `speak`
```
class  Mammal(Animal):
	def  speak(self):
		pass
```
Here we are creating a class named as `Dog` which is inheriting the properties of `Mammal` class, which is inherting the properties of `Animal` class and inside this we are making a function named as `speak`
```
class  Dog(Mammal):
	def  speak(self):
		print("Woof!") 
```
Here we are creating a object `Dog` class and passing a value in its constructor and callinf the function and priting them.
```
dog = Dog("Rover")
print(dog.name) # output "Rover" 
dog.speak() # output "Woof!"
```
## Polymorphism :-
It refers to the ability of objects of different classes to be used interchangeably, as long as they share a common interface or base class.
Here is a example :- Here we are creating a class named as `Animal` and creating a function named as `speak` inside it.
```
class Animal:
    def speak(self):
        print("The animal makes a sound")
```
Here we are creating a class named as `Dog` which is inherited by `Animal` class and creating a function named as `speak` inside it.
```
class Dog(Animal):
    def speak(self):
        print("The dog barks")
```
Here we are creating a class named as `Cat` which is inherited by `Animal` class and creating a function named as `speak` inside it.
```
class Cat(Animal):
    def speak(self):
        print("The cat meows")
```
Here we are creating objects of class `Dog`,`Cat` named as `dog` ,`cat` and callingg the `speak` function
```
dog = Dog()
cat = Cat()
dog.speak()  # Outputs "The dog barks"
cat.speak()  # Outputs "The cat meows"
```
## Encapsulation :-
It refers to the practice of hiding the internal details of an object and providing a public interface for interacting with the object. Encapsulation is achieved through access modifiers, which control the visibility and accessibility of an object's attributes and methods

Here is a example :-
```
class People:
    def __init__(self, name, gender):
        self._name = name
        self._gender = gender

    def get_name(self):
        return self._name

    def set_name(self, name):
        self._name = name

person1 = People("Ankit", "Male")
print(person1.get_name())  # output: Ankit
person1.set_name("Aman")
print(person1.get_name())  # output: Aman
```
## Abstraction :-
It refers to the practice of hiding the complexity of an object and exposing only the essential features or interface that the user needs to interact with the object. Abstraction is achieved through abstract classes and abstract methods, which define a common interface for a group of related classes.
Here is the example :-
```
from abc import ABC, abstractmethod

class People(ABC):
    def __init__(self, name, gender):
        self.name = name
        self.gender = gender

    @abstractmethod
    def speak(self):
        pass

class Male(Animal):
    def speak(self):
        print("Hello")

class Female(Animal):
    def speak(self):
        print("Hi")

male1 = Male("Ankit", "Male")
female1 = Female("Sona", "Female")

male1.speak()  # output: Hello
female1.speak()  # output: Hi
```