OOP python
OOP python
1. Classes
Theory:
A class is a blueprint for creating objects. It defines properties (attributes) and behaviors
(methods) that its objects can have.
class Animal:
species = "Unknown" # Class attribute
2. Objects (Instances)
Theory:
Objects are specific instances of a class. They hold data and methods defined by their class.
3. Attributes
Theory:
Attributes are variables that store data about an object. They can be unique (instance
attributes) or shared (class attributes).
class Animal:
species = "Mammal" # Class attribute
dog = Animal("Buddy")
print(dog.name) # Instance attribute
print(dog.species) # Class attribute
4. Methods
Theory:
Functions defined in a class to manipulate attributes or define behavior.
class Math:
@staticmethod
def add(a, b):
return a + b
@classmethod
def info(cls):
return f"This is a {cls.__name__} class"
5. Constructor (__init__)
Theory:
The __init__ method is called automatically when an object is created. It initializes the
instance attributes.
class Animal:
def __init__(self, name, age):
self.name = name
self.age = age
dog = Animal("Buddy", 5)
print(dog.name, dog.age) # Output: Buddy 5
6. Inheritance
Theory:
Inheritance allows one class (child) to inherit attributes and methods from another class
(parent).
# Single Inheritance
class Animal:
def speak(self):
return "Animal sound"
class Dog(Animal):
def speak(self):
return "Bark"
dog = Dog()
print(dog.speak()) # Output: Bark
7. Encapsulation
Theory:
Encapsulation restricts access to certain parts of an object. Use private ( __) or protected (_)
attributes for encapsulation.
class Animal:
def __init__(self, name):
self.__name = name # Private attribute
dog = Animal("Buddy")
print(dog.get_name()) # Output: Buddy
dog.set_name("Max")
print(dog.get_name()) # Output: Max
8. Abstraction
Theory:
Abstraction hides implementation details and shows only essential features. Abstract
classes and methods are used to achieve this.
class Animal(ABC):
@abstractmethod
def speak(self):
pass
class Dog(Animal):
def speak(self):
return "Bark"
dog = Dog()
print(dog.speak()) # Output: Bark
9. Polymorphism
Theory:
Polymorphism allows the same function to behave differently based on the context.
# Method Overriding
class Animal:
def speak(self):
return "Animal sound"
class Dog(Animal):
def speak(self):
return "Bark"
dog = Dog()
print(dog.speak()) # Output: Bark
Theory:
Determines the order in which methods are inherited in a multiple-inheritance scenario.
class A:
def method(self):
return "A"
class B(A):
pass
class C(A):
def method(self):
return "C"
obj = D()
print(obj.method()) # Output: C
Theory:
super() is used to call methods of a parent class.
class Parent:
def greet(self):
return "Hello from Parent"
class Child(Parent):
def greet(self):
return super().greet() + " and Child"
child = Child()
print(child.greet()) # Output: Hello from Parent and Child
Theory:
Special methods with double underscores, used for operator overloading and custom
behavior.
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
p1 = Point(1, 2)
p2 = Point(3, 4)
result = p1 + p2
print(result.x, result.y) # Output: 4 6
13. Composition
Theory:
A "has-a" relationship where one class contains another.
class Engine:
def start(self):
return "Engine started"
class Car:
def __init__(self):
self.engine = Engine()
def drive(self):
return self.engine.start()
car = Car()
print(car.drive()) # Output: Engine started
14. Aggregation
Theory:
A weaker form of composition where objects are shared.
class Department:
def __init__(self, name):
self.name = name
class Employee:
def __init__(self, name, department):
self.name = name
self.department = department
dept = Department("IT")
emp = Employee("Alice", dept)
print(emp.department.name) # Output: IT
Theory:
Defines a contract that implementing classes must follow. In Python, use abstract classes or
protocols.
Theory:
If an object behaves like a duck (has the required methods), it is treated as a duck.
class Bird:
def fly(self):
return "Flying"
class Airplane:
def fly(self):
return "Flying high"
def let_fly(obj):
print(obj.fly())
bird = Bird()
plane = Airplane()
let_fly(bird) # Output: Flying
let_fly(plane) # Output: Flying high
Theory:
Type checking ensures that an object is of a specific type or class.
class Animal:
pass
class Dog(Animal):
pass
dog = Dog()
Theory:
Inheritance allows child classes to reuse parent class attributes and methods. The super()
keyword is used to access methods of the parent class.
class Parent:
def greet(self):
return "Hello from Parent"
class Child(Parent):
def greet(self):
return super().greet() + " and Child"
child = Child()
print(child.greet()) # Output: Hello from Parent and Child
Theory:
self represents the instance of the class and is used to access attributes and methods of the
object.
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
return f"{self.name} says Hello!"
dog = Animal("Buddy")
print(dog.speak()) # Output: Buddy says Hello!
Theory:
The @property decorator is used to define getter methods, allowing attributes to be
accessed like properties.
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def radius(self):
return self._radius
@radius.setter
def radius(self, value):
if value > 0:
self._radius = value
else:
raise ValueError("Radius must be positive!")
circle = Circle(5)
print(circle.radius) # Output: 5
circle.radius = 10
print(circle.radius) # Output: 10
Theory:
class Animal:
species = "Mammal" # Class variable
dog = Animal("Buddy")
cat = Animal("Kitty")
print(dog.species) # Mammal (class variable)
print(cat.name) # Kitty (instance variable)
Theory:
class Animal:
def __init__(self):
self.public_attr = "Public"
self._protected_attr = "Protected"
self.__private_attr = "Private"
def get_private_attr(self):
return self.__private_attr
animal = Animal()
print(animal.public_attr) # Public
print(animal._protected_attr) # Protected
print(animal.get_private_attr()) # Private
Theory:
Decorators like @classmethod, @staticmethod, and @property modify class methods'
behavior.
class Math:
@staticmethod
def add(a, b):
return a + b
@classmethod
def info(cls):
return f"This is a {cls.__name__} class"
class MyIterator:
def __init__(self, max):
self.max = max
self.current = 0
def __iter__(self):
return self
def __next__(self):
if self.current < self.max:
self.current += 1
return self.current
else:
raise StopIteration
it = MyIterator(3)
for num in it:
print(num) # Output: 1, 2, 3
Theory:
Context managers handle resources like files, ensuring proper cleanup.
class FileManager:
def __init__(self, filename, mode):
self.file = open(filename, mode)
def __enter__(self):
return self.file
Theory:
Redefining how operators work for user-defined types.
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
return Point(self.x + other.x, self.y + other.y)
p1 = Point(1, 2)
p2 = Point(3, 4)
result = p1 + p2
print(result.x, result.y) # Output: 4 6
Theory:
Customize string representation of objects using __str__ and __repr__.
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
return f"Point({self.x}, {self.y})"
p = Point(3, 4)
print(p) # Output: Point(3, 4)
Theory:
class Example:
@staticmethod
def static_method():
return "Static Method"
@classmethod
def class_method(cls):
return f"Class Method in {cls.__name__}"
Theory:
Abstract classes enforce implementation of abstract methods in child classes.
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self):
pass
class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
rect = Rectangle(4, 5)
print(rect.area()) # Output: 20
These examples cover the remaining concepts in OOP comprehensively. Let me know if
you need further clarification!