Mastering Python: OOP-Encapsulation, Abstraction and Polymorphism(Part-2)
Before reading this article, please read Part-1 first.
Encapsulation
This is the packaging of data and functions in classes correspondingly. Object-orientated programming allows a simple package to handle data and function together. This makes programmers capable to detect bugs and errors during programming. When a programmer finds a mistake, it makes programmer easier to fix it. Although it is possible to define functions and assign variables, like with procedural programming, there is no unit or structure meant to package them.
This places regulations on having access to variables and methods directly and may save you the unintentional change of data. To save you unintentional change, the object variable can only be changed by an object’s method. Those types of variables are known as private variables.
A class is an example of encapsulation as it encapsulates all the data that is member functions, variables, etc. The goal of information hiding is to ensure that an object’s state is always valid by controlling access to attributes that are hidden from the outside world.
For example, consider a class that represents a car. This class might have attributes like the make, model, and year of the car, as well as methods like start, stop, and accelerate. Encapsulation would mean that the internal workings of these methods are hidden from the outside world, and the only way to access or modify the data is through the methods provided by the class. This makes it easier for other programmers to use the class, because they don’t need to know how the methods are implemented in order to use them.
Here is a simple example of encapsulation in OOP:
class Car:
def __init__(self, make, model, year):
self.make = make
self.model = model
self.year = year
def start(self):
print("Starting car")
def stop(self):
print("Stopping car")
def accelerate(self):
print("Accelerating car")
In this example, the Car
class encapsulates the data (make, model, and year) and the methods (start, stop, and accelerate) that operate on that data. The only way to access or modify the data is through the methods provided by the class. Other programmers can use the Car
class without needing to know how the methods are implemented, making it easier to use and maintain.
Python Access Modifiers
In Python, access modifiers are keywords that are used to specify the level of access that a class member (attribute or method) has. These keywords are public
, protected
, and private
.
- Public: These are the methods, attributes, or classes that are accessible from anywhere in the code.
- Protected: These are the methods, attributes, or classes that are accessible only from within the class and its subclasses.
- Private: These are the methods, attributes, or classes that are accessible only from within the class itself.
These access modifiers are not enforced by the Python interpreter, but rather serve as a convention for developers to follow when designing their classes.
Here is an example of using access modifiers in Python:
class MyClass:
# public attribute
public_attr = 'I am a public attribute'
# protected attribute
_protected_attr = 'I am a protected attribute'
# private attribute
__private_attr = 'I am a private attribute'
# public method
def public_method(self):
print('I am a public method')
# protected method
def _protected_method(self):
print('I am a protected method')
# private method
def __private_method(self):
print('I am a private method')
In this example, the public_attr
, public_method()
, _protected_attr
, and _protected_method()
can be accessed from anywhere in the code. The __private_attr
and __private_method()
are only accessible from within the MyClass
class itself.
The main advantage of using access modifiers in Python is that they provide a way to control the visibility and accessibility of class attributes and methods. This is important because it allows you to create classes that have a well-defined interface and that can be used in a predictable and consistent way.
For example, by using access modifiers, you can make sure that certain attributes and methods are only accessible from within the class, or from its subclasses. This allows you to create classes that are well-encapsulated, which makes them easier to maintain and debug.
Additionally, using access modifiers can help prevent unintended modifications to class attributes and methods, which can help to prevent bugs and other problems in your code.
Overall, access modifiers are an important tool for creating well-structured and maintainable Python classes.
Abstraction
Abstraction is a fundamental principle of object-oriented programming that involves separating the essential characteristics of an object from its internal implementation details. The idea is to focus on the essential characteristics and behavior of an object, and hide the internal details from the user. This helps to reduce complexity and improve modularity, making it easier to understand and use the object.
Here’s an example of abstraction in Python:
class BankAccount:
def __init__(self, balance):
self.balance = balance
def deposit(self, amount):
self.balance += amount
def withdraw(self, amount):
self.balance -= amount
def get_balance(self):
return self.balance
In this example, the BankAccount
class represents a bank account object. The __init__
method is a special method in Python that is called when an object is created, and it is used to initialize the object. The deposit
, withdraw
, and get_balance
methods represent the essential behavior of a bank account, allowing the user to deposit and withdraw money, and check the balance.
The internal implementation details of how the balance is stored and updated are hidden from the user. The user only needs to know the essential behavior of the object, and can use the object without worrying about the implementation details. This is an example of abstraction in object-oriented programming.
There are several advantages to using abstraction in Python:
- Abstraction helps to reduce complexity by hiding unnecessary details from the user. This makes it easier for the user to understand and use the object, as they only need to know the essential characteristics and behavior.
- Abstraction promotes modularity, as it allows the object to be used as a standalone entity without exposing its internal implementation details. This makes it easier to reuse the object in different contexts, and to test and debug the object.
- Abstraction allows for flexibility, as the internal implementation details of the object can be changed without affecting how the object is used. This makes it easier to maintain and evolve the object over time.
- Abstraction can help to improve the security of an object, as it allows the object to be used without exposing sensitive information or vulnerabilities.
- Abstraction is a fundamental principle of object-oriented programming, and is widely used in Python and other programming languages. Understanding and using abstraction can help you to design more robust and scalable object-oriented systems.
Polymorphism
Polymorphism is a concept in object-oriented programming that allows objects of different classes to have the same interface (methods and properties), but with different implementations. This means that an object can be used in the same way, regardless of its specific class, as long as it has the required interface.
Here’s an example of polymorphism in Python:
class Animal:
def speak(self):
raise NotImplementedError
class Dog(Animal):
def speak(self):
return "Bark!"
class Cat(Animal):
def speak(self):
return "Meow!"
def make_animal_speak(animal):
return animal.speak()
dog = Dog()
cat = Cat()
print(make_animal_speak(dog)) # Output: "Bark!"
print(make_animal_speak(cat)) # Output: "Meow!"
In this example, the Animal
class has a speak
method that is not implemented. The Dog
and Cat
classes both inherit from the Animal
class, and they each have their own implementation of the speak
method. The make_animal_speak
function takes an Animal
object as an argument and calls its speak
method.
The dog
and cat
objects are both of different classes (Dog
and Cat
), but they both have the required speak
method, and can be used with the make_animal_speak
function in the same way. This is an example of polymorphism in Python, as the dog
and cat
objects have the same interface (the speak
method), but different implementations.
There are several advantages to using polymorphism in Python:
- Polymorphism allows objects of different classes to be used in the same way, as long as they have the required interface. This means that you can write code that is more flexible and reusable, as it can work with a range of different objects without needing to know their specific class.
- Polymorphism promotes modularity, as it allows you to write code that is decoupled from the specific implementation details of an object. This makes it easier to change and evolve the object over time, without affecting the code that uses it.
- Polymorphism can help to improve the readability and maintainability of your code, as it allows you to express the behavior of an object in a more abstract and general way.
- Polymorphism is a powerful tool for designing object-oriented systems, and is widely used in Python and other programming languages. Understanding and using polymorphism can help you to design more robust and scalable object-oriented systems.
Conclusion of this chapter
Object-oriented programming (OOP) is a programming paradigm that is based on the concept of “objects”, which represent real-world entities and the data and behavior associated with them. OOP has several advantages in Python:
- OOP promotes modularity and code reuse. Objects can be designed to be self-contained and reusable, which makes it easier to write and maintain code.
- OOP allows you to organize your code in a logical and hierarchical way, which can make it easier to understand and maintain.
- OOP allows you to encapsulate data and behavior, which promotes security and data integrity.
- OOP makes it easier to write code that can be easily extended and modified. You can create new objects by inheriting from existing other, and you can override or extend the behavior of an object by subclassing it.
- OOP is widely used in Python and other programming languages, and is a powerful tool for designing scalable and maintainable software systems. Understanding and using OOP can help you to write better-structured and more reusable code.
We will continue to the next chapter, Implementation of Object-Oriented Programming in Python.