Polymorphism means “many forms”. In OOP, it allows the same method name (or operator) to behave differently depending on the object or data type it is acting upon.
It helps in:
Code reusability
Flexibility
Maintainability
Types of Polymorphism in Python
Python mainly supports runtime polymorphism (method overriding) and compile-time-like polymorphism (method overloading via default arguments or *args).
1. Polymorphism with Functions and Objects
A single function can work with different types of objects.
Python
# Example: Same function name, different object types
classDog:
defspeak(self):
return"Woof!"
classCat:
defspeak(self):
return"Meow!"
defanimal_sound(animal):
print(animal.speak())
# Using polymorphism
dog=Dog()
cat=Cat()
animal_sound(dog)# Woof!
animal_sound(cat)# Meow!
Here, animal_sound() works with any object that has a .speak() method — this is duck typing in Python.
2. Polymorphism with Inheritance (Method Overriding)
Child classes can override methods from the parent class.
Python
classBird:
deffly(self):
return"Some birds can fly."
classSparrow(Bird):
deffly(self):
return"Sparrow flies high."
classPenguin(Bird):
deffly(self):
return"Penguins can't fly."
# Runtime polymorphism
forbirdin[Sparrow(),Penguin()]:
print(bird.fly())
Output:
Sparrow flies high.
Penguins can't fly.
3. Polymorphism with Built-in Functions
Many built-in functions in Python are polymorphic.
Python
print(len("Hello"))# Works on string → 5
print(len([1,2,3]))# Works on list → 3
4. Operator Overloading (Special Methods)
Operators like +, *, etc., behave differently for different data types.
print(5 + 10) # Integer addition → 15
print("Hi " + "Py") # String concatenation → Hi Py
You can define custom behavior using magic methods:
Python
classBook:
def__init__(self,pages):
self.pages=pages
def__add__(self,other):
returnself.pages+other.pages
b1=Book(100)
b2=Book(200)
print(b1+b2)# 300
Sure! Let’s break down polymorphism in Python in the context of Object-Oriented Programming (OOP).
Key Takeaways
Polymorphism lets the same interface work for different data types or classes.
In Python, it’s often achieved through method overriding, duck typing, and operator overloading.
It improves code flexibility and reduces duplication.
If you want, I can prepare a single Python program that demonstrates all types of polymorphism in one place for easy learning. Do you want me to create that?
Inheritance is a fundamental concept in object-oriented programming (OOP) that allows a class to inherit attributes and methods from another class. This promotes code reusability and establishes a hierarchical relationship between classes.
Basic Syntax and Example
In Python, inheritance is implemented by defining a new class that derives from an existing class. The derived class (child class) inherits the attributes and methods of the base class (parent class). Here is a basic example:
Python
# Parent class
classPerson:
def__init__(self,name,id):
self.name=name
self.id=id
defdisplay(self):
print(self.name,self.id)
# Child class
classEmployee(Person):
defprint_emp(self):
print("Employee class called")
# Creating an object of the child class
emp=Employee("John",101)
emp.display()# Calling parent class method
emp.print_emp()# Calling child class method
In this example, the Employee class inherits from the Person class, allowing it to use the display method defined in the Person class.
Types of Inheritance
Python supports several types of inheritance:
Single Inheritance: A child class inherits from a single parent class.
Multiple Inheritance: A child class inherits from multiple parent classes.
Multilevel Inheritance: A child class inherits from a parent class, which in turn inherits from another parent class.
Hierarchical Inheritance: Multiple child classes inherit from the same parent class.
Hybrid Inheritance: A combination of two or more types of inheritance.
Method Overriding and super()
Method overriding allows a child class to provide a specific implementation for a method that is already defined in its parent class. The super() function is used to call a method from the parent class.
Python
classAnimal:
defspeak(self):
return"Some sound"
classDog(Animal):
defspeak(self):
return"Woof!"
# Creating an instance of the Dog class
dog=Dog()
print(dog.speak())# Output: Woof!
In this example, the Dog class overrides the speak method of the Animal class.
Using super() Function
The super() function allows you to call methods from the parent class. This is useful for initializing the parent class’s attributes in the child class.
Python
classPerson:
def__init__(self,name,age):
self.name=name
self.age=age
classStudent(Person):
def__init__(self,name,age,grade):
super().__init__(name,age)
self.grade=grade
# Creating an instance of the Student class
student=Student("Alice",20,"A")
print(student.name,student.age,student.grade)# Output: Alice 20 A
In this example, super().__init__(name, age) calls the __init__ method of the Person class to initialize the name and age attributes.
Conclusion
Inheritance in Python is a powerful feature that promotes code reusability and allows for the creation of a hierarchical relationship between classes. By understanding and utilizing inheritance, you can create more efficient and maintainable code.
Abstraction is a fundamental concept in Object-Oriented Programming (OOP) that focuses on hiding the internal implementation details of a class or method while exposing only the necessary functionality. This simplifies code interaction, reduces complexity, and enhances maintainability.
In Python, abstraction is achieved using abstract classes and abstract methods, which are defined in the abc module.
Abstract Classes and Methods
An abstract class serves as a blueprint for other classes. It cannot be instantiated directly and must be subclassed. Abstract classes contain one or more abstract methods, which are declared but not implemented. Subclasses must provide their own implementation for these methods.
For example:
Python
fromabcimportABC,abstractmethod
# Abstract class
classAnimal(ABC):
@abstractmethod
defmake_sound(self):
pass# Abstract method with no implementation
# Concrete subclass
classDog(Animal):
defmake_sound(self):
return"Bark"
# Instantiate the subclass
dog=Dog()
print(dog.make_sound())# Output: Bark
In this example, Animal is an abstract class with an abstract method make_sound(). The Dog class implements the method, allowing it to be instantiated.
Key Components of Abstraction
Abstract Methods: Declared using the @abstractmethod decorator, these methods must be implemented by subclasses.
Concrete Methods: Fully implemented methods in an abstract class that can be inherited by subclasses.
Abstract Properties: Declared using @property and @abstractmethod, these enforce property implementation in subclasses.
Example of Abstract Properties
Python
fromabcimportABC,abstractmethod
classVehicle(ABC):
@property
@abstractmethod
defwheels(self):
pass
classCar(Vehicle):
@property
defwheels(self):
return4
car=Car()
print(car.wheels)# Output: 4
Here, wheels is an abstract property in the Vehicle class, and the Car class provides its implementation.
Benefits of Abstraction
Simplifies Code: Users interact with high-level functionality without worrying about internal details.
Encapsulation: Sensitive or unnecessary details are hidden, reducing misuse or accidental changes.
Flexibility: Subclasses can define specific behaviors while adhering to a consistent structure.
Maintainability: Internal changes in abstract classes do not affect external code.
Important Considerations
Abstract classes cannot be instantiated directly. Attempting to do so raises a TypeError.
Subclasses must implement all abstract methods and properties; otherwise, they too become abstract and cannot be instantiated.
Example of Instantiation Error
Python
fromabcimportABC,abstractmethod
classShape(ABC):
@abstractmethod
defarea(self):
pass
# Attempting to instantiate an abstract class
shape=Shape()# Raises TypeError
Abstraction in Python is a powerful tool for designing robust and scalable applications by enforcing a clear structure and hiding unnecessary complexity.
You are given an array of integers nums, there is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves right by one position.