Python OOP: Classes, Objects, Inheritance, Polymorphism & Encapsulation
1. What are classes and objects in Python?
Q: What are classes and objects?
A class is a blueprint for creating objects, defining attributes (data) and methods (functions). Syntax: class ClassName:.
An object is an instance of a class, created to access its attributes and methods. Creation: obj = ClassName().
Use Case: Modeling real-world entities (e.g., employees, cars) with reusable code.
2. Can you give an example of classes and objects?
class Employee:
def __init__(self, name, salary):
self.name = name
self.salary = salary
def display_info(self):
return f"Name: {self.name}, Salary: ${self.salary}"
# Creating objects
emp1 = Employee("Krishna", 60000)
emp2 = Employee("Kristal", 55000)
# Accessing methods
print(emp1.display_info())
print(emp2.display_info())
Output:
Name: Krishna, Salary: $60000
Name: Kristal, Salary: $55000
Note: Employee is the class; emp1 and emp2 are objects. __init__ initializes object attributes.
3. What is the __init__ method in Python?
Q: What is __init__?
Definition: A special (magic) method called a constructor, automatically invoked when an object is created.
Syntax: def __init__(self, *args, **kwargs):.
Purpose: Initializes instance variables for the object.
Use Case: Setting up initial state (e.g., name, ID) for objects.
4. Can you give an example of the __init__ method?
class Car:
def __init__(self, brand, model):
self.brand = brand
self.model = model
def car_info(self):
return f"Car: {self.brand} {self.model}"
# Creating objects with __init__
car1 = Car("Toyota", "Camry")
car2 = Car("Honda", "Civic")
print(car1.car_info())
print(car2.car_info())
Output:
Car: Toyota Camry
Car: Honda Civic
Note: __init__ sets brand and model for each Car object. self refers to the instance being created.
5. What are instance and class variables in Python?
Q: Instance vs class variables?
Instance Variables: Unique to each object, defined in __init__ or other methods using self. Example: self.name.
Class Variables: Shared across all instances of a class, defined directly in the class body. Example: company_name shared by all Employee objects.
Use Case: Instance variables for object-specific data; class variables for shared data.
6. Can you give an example of instance vs. class variables?
class Employee:
company_name = "TechCorp" # Class variable
def __init__(self, name, salary):
self.name = name # Instance variable
self.salary = salary # Instance variable
def info(self):
return f"{self.name} at {self.company_name}, Salary: ${self.salary}"
# Creating objects
emp1 = Employee("Krishna", 60000)
emp2 = Employee("Kristal", 55000)
print(emp1.info())
print(emp2.info())
# Modifying class variable
Employee.company_name = "NewTech"
print(emp1.info()) # Reflects updated class variable
Output:
Krishna at TechCorp, Salary: $60000
Kristal at TechCorp, Salary: $55000
Krishna at NewTech, Salary: $60000
Note: company_name is shared; name and salary are unique per object. Changing company_name affects all instances.
7. What are inheritance and method overriding in Python?
Q: What is inheritance and overriding?
Inheritance: A class (child) inherits attributes and methods from another class (parent). Syntax: class ChildClass(ParentClass):.
Method Overriding: Child class provides a specific implementation of a parent class method. Access parent with super().
Use Case: Reusing and extending code (e.g., specialized employee types).
8. Can you give an example of inheritance and method overriding?
class Person:
def __init__(self, name):
self.name = name
def describe(self):
return f"Person: {self.name}"
class Employee(Person):
def __init__(self, name, salary):
super().__init__(name)
self.salary = salary
def describe(self): # Override parent method
return f"Employee: {self.name}, Salary: ${self.salary}"
# Creating objects
person = Person("Krishna")
employee = Employee("Kristal", 55000)
print(person.describe())
print(employee.describe())
Output:
Person: Krishna
Employee: Kristal, Salary: $55000
Note: Employee inherits from Person; super().__init__ calls parent's constructor. describe is overridden in Employee.
9. What are polymorphism and encapsulation in Python?
Q: What are polymorphism and encapsulation?
Polymorphism: Objects of different classes can be treated as instances of a common parent class, using shared method names differently.
Encapsulation: Restricting access to data and methods, typically using private attributes (_ or __). Double underscore triggers name mangling.
Use Case: Polymorphism for flexible interfaces; encapsulation for data protection.
10. Can you give an example of polymorphism and encapsulation?
class Employee:
def __init__(self, name, salary):
self.name = name
self.__salary = salary # Private attribute
def describe(self):
return f"Employee: {self.name}"
def get_salary(self):
return self.__salary
class Manager(Employee):
def describe(self): # Polymorphic method
return f"Manager: {self.name}"
# Polymorphism
employees = [Employee("Krishna", 60000), Manager("Kristal", 80000)]
for emp in employees:
print(emp.describe())
# Encapsulation
emp = Employee("Ram", 55000)
print(f"Salary via getter: ${emp.get_salary()}")
Output:
Employee: Krishna
Manager: Kristal
Salary via getter: $55000
Note: Polymorphism: describe behaves differently. Encapsulation: __salary is private, accessed via getter.
11. What are class methods, static methods, and magic methods?
Q: What are class/static methods?
Class Methods: Use @classmethod, receive cls (the class), often for alternative constructors.
Static Methods: Use @staticmethod, utility functions that don't need self or cls.
Magic Methods (dunder): Special methods like __str__, __len__, __add__ that customize object behavior.
12. Best Practices for Python OOP
Q: What are OOP best practices?
- Use CamelCase for class names, snake_case for methods/variables.
- Always implement
__init__and__str__/__repr__. - Prefer composition over deep inheritance hierarchies.
- Encapsulate data with private attributes and getters/setters.
- Use
super()properly in inheritance. - Follow the Single Responsibility Principle.
- Document classes/methods with docstrings.
- Test edge cases and use type hints where helpful.