Classes and Objects

  • Classes: A blueprint for creating objects. Defines the properties (attributes) and behaviors (methods) of the objects.

Example:

  class Dog:
    def __init__(self, name, breed):
        self.name = name
        self.breed = breed
    
    def bark(self):
        return f"{self.name} says woof!"

# Creating an object (instance) of the class
my_dog = Dog("Buddy", "Golden Retriever")
print(my_dog.bark())
  
  • Objects: Instances of a class. Each object can have different attributes, even if they are created from the same class.

Inheritance and Polymorphism

Inheritance: A mechanism that allows a new class (child class) to inherit attributes and methods from an existing class (parent class).

Example:

  class Animal:
    def __init__(self, name):
        self.name = name
    
    def speak(self):
        return f"{self.name} makes a sound."

class Dog(Animal):
    def speak(self):
        return f"{self.name} barks."

my_dog = Dog("Buddy")
print(my_dog.speak())
  
  • Polymorphism: The ability to use a common interface for multiple forms (data types). In Python, polymorphism is often seen through method overriding in inheritance.

Example:

  class Cat(Animal):
    def speak(self):
        return f"{self.name} meows."

animals = [Dog("Buddy"), Cat("Whiskers")]

for animal in animals:
    print(animal.speak())  # Polymorphism in action
  

Encapsulation and Abstraction

  • Encapsulation: The concept of wrapping data (attributes) and methods (functions) that operate on the data within a single unit or class. It restricts direct access to some of the object’s components, which is known as data hiding.

Example:

  class Car:
    def __init__(self, make, model):
        self.__make = make  # Private attribute
        self.__model = model

    def get_make(self):
        return self.__make  # Accessor method

my_car = Car("Toyota", "Corolla")
print(my_car.get_make())  # Accessing the private attribute via a method
  
  • Abstraction: The concept of hiding the complex implementation details and showing only the necessary features of an object. Abstraction is achieved through abstract classes and methods in some programming languages, though in Python, it’s more about designing simple interfaces.

Example:

  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

my_rectangle = Rectangle(10, 20)
print(my_rectangle.area())
  

Method Overriding and Overloading

  • Method Overriding: A feature that allows a child class to provide a specific implementation of a method that is already defined in its parent class.

Example:

  class Animal:
    def speak(self):
        return "Some sound"

class Dog(Animal):
    def speak(self):
        return "Bark"

my_dog = Dog()
print(my_dog.speak())  # Overrides the parent class method
  
  • Method Overloading: Python doesn’t support traditional method overloading (having multiple methods with the same name but different parameters). However, you can achieve similar behavior using default parameters or variable-length arguments.

Example:

  Copy code
class Calculator:
    def add(self, a, b, c=0):
        return a + b + c

calc = Calculator()
print(calc.add(2, 3))      # Two arguments
print(calc.add(2, 3, 5))   # Three arguments