> ## Documentation Index
> Fetch the complete documentation index at: https://ai.tharung.in/llms.txt
> Use this file to discover all available pages before exploring further.

# Python Oops

## Introduction to OOP

Object-Oriented Programming (OOP) is a programming approach that organizes programs using **classes** and **objects**. It models real-world entities, making code reusable, modular, secure, and easier to maintain.

***

# 1. Class

A **class** is a blueprint or template used to create objects. It defines the data (attributes) and behavior (methods) that objects will have.

### Example

```python theme={null}
class Student:
    def display(self):
        print("This is a Student class.")

s = Student()
s.display()
```

**Output**

```text theme={null}
This is a Student class.
```

***

# 2. Object

An **object** is an instance of a class. It represents a real entity and can access the class's variables and methods.

### Example

```python theme={null}
class Car:
    def start(self):
        print("Car Started")

c = Car()
c.start()
```

**Output**

```text theme={null}
Car Started
```

***

# 3. Constructor (`__init__`)

A constructor is a special method that is automatically called whenever an object is created. It is mainly used to initialize object variables.

### Example

```python theme={null}
class Student:
    def __init__(self, name):
        self.name = name

s = Student("Alice")
print(s.name)
```

**Output**

```text theme={null}
Alice
```

***

# 4. `self` Keyword

`self` refers to the current object of the class. It is used to access instance variables and instance methods.

### Example

```python theme={null}
class Student:
    def __init__(self, name):
        self.name = name

    def show(self):
        print(self.name)

s = Student("David")
s.show()
```

**Output**

```text theme={null}
David
```

***

# 5. Instance Variables

Instance variables belong to an object. Every object has its own separate copy.

### Example

```python theme={null}
class Student:
    def __init__(self, name):
        self.name = name

s1 = Student("John")
s2 = Student("Emma")

print(s1.name)
print(s2.name)
```

**Output**

```text theme={null}
John
Emma
```

***

# 6. Instance Methods

Instance methods work with object data and always receive `self` as the first parameter.

### Example

```python theme={null}
class Student:
    def show(self):
        print("Instance Method")

s = Student()
s.show()
```

**Output**

```text theme={null}
Instance Method
```

***

# 7. Class Variables

Class variables belong to the class itself and are shared among all objects.

### Example

```python theme={null}
class Student:
    school = "ABC School"

s1 = Student()
s2 = Student()

print(s1.school)
print(s2.school)
```

**Output**

```text theme={null}
ABC School
ABC School
```

***

# 8. Class Methods (`@classmethod`)

Class methods work with class variables. They receive `cls` instead of `self`.

### Example

```python theme={null}
class Student:
    school = "ABC School"

    @classmethod
    def show_school(cls):
        print(cls.school)

Student.show_school()
```

**Output**

```text theme={null}
ABC School
```

***

# 9. Static Methods (`@staticmethod`)

Static methods do not use instance variables or class variables. They behave like normal functions inside a class.

### Example

```python theme={null}
class Math:
    @staticmethod
    def add(a, b):
        return a + b

print(Math.add(5, 3))
```

**Output**

```text theme={null}
8
```

***

# 10. Encapsulation

Encapsulation combines data and methods into a single class while controlling access to the data.

### Example

```python theme={null}
class Bank:
    def __init__(self):
        self.__balance = 5000

    def show_balance(self):
        print(self.__balance)

b = Bank()
b.show_balance()
```

**Output**

```text theme={null}
5000
```

***

# 11. Access Modifiers

## Public

Public members can be accessed from anywhere.

```python theme={null}
class Student:
    def __init__(self):
        self.name = "Alice"

s = Student()
print(s.name)
```

***

## Protected

Protected members are indicated using a single underscore (`_`). They are intended for internal use and subclasses.

```python theme={null}
class Student:
    def __init__(self):
        self._marks = 90

s = Student()
print(s._marks)
```

***

## Private

Private members use double underscores (`__`) and cannot be accessed directly outside the class.

```python theme={null}
class Student:
    def __init__(self):
        self.__age = 20

    def show(self):
        print(self.__age)

s = Student()
s.show()
```

***

# 12. Inheritance

Inheritance allows a child class to reuse the properties and methods of a parent class.

### Example

```python theme={null}
class Animal:
    def sound(self):
        print("Animal Sound")

class Dog(Animal):
    pass

d = Dog()
d.sound()
```

**Output**

```text theme={null}
Animal Sound
```

***

# 13. Types of Inheritance

### Single Inheritance

```python theme={null}
class A:
    pass

class B(A):
    pass
```

### Multiple Inheritance

```python theme={null}
class A:
    pass

class B:
    pass

class C(A, B):
    pass
```

### Multilevel Inheritance

```python theme={null}
class A:
    pass

class B(A):
    pass

class C(B):
    pass
```

### Hierarchical Inheritance

```python theme={null}
class A:
    pass

class B(A):
    pass

class C(A):
    pass
```

### Hybrid Inheritance

Combination of two or more inheritance types.

***

# 14. Polymorphism

Polymorphism allows the same method name to perform different actions depending on the object.

### Example

```python theme={null}
class Dog:
    def sound(self):
        print("Bark")

class Cat:
    def sound(self):
        print("Meow")

for animal in (Dog(), Cat()):
    animal.sound()
```

**Output**

```text theme={null}
Bark
Meow
```

***

# 15. Method Overriding

Method overriding occurs when a child class provides its own version of a parent class method.

### Example

```python theme={null}
class Animal:
    def sound(self):
        print("Animal Sound")

class Dog(Animal):
    def sound(self):
        print("Bark")

d = Dog()
d.sound()
```

**Output**

```text theme={null}
Bark
```

***

# 16. Operator Overloading

Operator overloading allows operators such as `+`, `-`, and `*` to work with user-defined objects.

### Example

```python theme={null}
class Number:
    def __init__(self, value):
        self.value = value

    def __add__(self, other):
        return self.value + other.value

n1 = Number(10)
n2 = Number(20)

print(n1 + n2)
```

**Output**

```text theme={null}
30
```

***

# 17. Abstraction

Abstraction hides implementation details and exposes only the essential features.

### Example

```python theme={null}
from abc import ABC, abstractmethod

class Shape(ABC):

    @abstractmethod
    def area(self):
        pass

class Square(Shape):
    def area(self):
        print("Area = side × side")

s = Square()
s.area()
```

**Output**

```text theme={null}
Area = side × side
```

***

# 18. `super()` Function

`super()` is used to call the parent class constructor or methods.

### Example

```python theme={null}
class Parent:
    def __init__(self):
        print("Parent Constructor")

class Child(Parent):
    def __init__(self):
        super().__init__()
        print("Child Constructor")

c = Child()
```

**Output**

```text theme={null}
Parent Constructor
Child Constructor
```

***

# 19. Magic (Dunder) Methods

Magic methods begin and end with double underscores. They define the behavior of objects.

### Common Magic Methods

* `__init__()` – Constructor
* `__str__()` – String representation
* `__len__()` – Returns object length
* `__add__()` – Operator overloading
* `__repr__()` – Official object representation

### Example

```python theme={null}
class Student:
    def __init__(self, name):
        self.name = name

    def __str__(self):
        return self.name

s = Student("Alice")
print(s)
```

**Output**

```text theme={null}
Alice
```

***

# 20. Object Introspection *(Additional Important Topic)*

Object introspection helps inspect an object's type, attributes, and inheritance.

### Common Functions

* `type()`
* `isinstance()`
* `issubclass()`
* `hasattr()`
* `getattr()`
* `setattr()`

### Example

```python theme={null}
class Student:
    pass

s = Student()

print(type(s))
print(isinstance(s, Student))
```

***

# 21. Four Pillars of OOP

### Encapsulation

Wrapping data and methods into a single class while restricting direct access.

### Abstraction

Hiding implementation details and exposing only essential functionality.

### Inheritance

Creating a new class from an existing class to reuse code.

### Polymorphism

Using the same interface or method name with different implementations.

***

# Advantages of OOP

* Code reusability
* Better maintainability
* Easy debugging
* Modular programming
* Data security through encapsulation
* Real-world problem modeling
* Improved scalability

***
