Four Major pillars of OOPs in Python | Learn Python |


The concept of objects, which can hold data and behave in specific ways, is the foundation of the object-oriented programming (OOP) paradigm. The four main ideas or pillars that OOP emphasizes are as follows:

  • Inheritance: Inheritance is the process of creating new classes by inheriting the properties and methods of existing classes. This allows for the reuse of code and the creation of more specialized classes.
  • Polymorphism: This term describes the interchangeability of items of various types. Because objects can be considered as either generic types or specialized types depending on the situation, this gives programmers more freedom.
  • Encapsulation: Encapsulation refers to hiding an object's internal details and exposing only the necessary information or methods to the outside world. This helps to ensure that the object's internal state is not modified or accessed in unexpected ways
  • Abstraction: Abstraction refers to the process of creating simplified representations of complex systems. In OOP, this is often achieved using abstract classes and interfaces, which define typical behavior and properties that can be shared among multiple classes. This makes the code simpler and easier to maintain and alter by lowering its complexity.
Inheritance

Inheritance is one of the key features of object-oriented programming (OOP) that allows a new class to be based on an existing class, inheriting its properties and methods. The new class is referred to as a child class or subclass, and the existing class is referred to as the parent class or superclass.

In Python, inheritance is implemented using the syntax class Subclass(ParentClass):. The child class can inherit all the attributes and methods of the parent class and can also add new attributes and methods or override the ones inherited from the parent class.

Here is an example of inheritance in Python:

example1.png

In this example, Animal is the parent class, and Dog and Cat are the child classes. Both Dog and Cat inherit the attribute's name and age from the parent class Animal through their respective __init__ methods. The child classes also override the make_sound method from the parent class with their own implementation.

Dog also has a new method called wag_tail and the added attribute breed. Cat now has a new purr technique and an additional attribute called color.

When a child class object is created, it can access both its own methods and attributes as well as all the methods and attributes of the parent class. For instance:

example2.png

Code can be reused because of inheritance, which also makes it possible to build new classes off of preexisting ones with little duplication of code.

Five inheritance patterns exist:
  • Single Inheritance
  • Multilevel Inheritance
  • Hierarchical Inheritance
  • Multiple Inheritance
  • Hybrid Inheritance

Single Inheritance



In object-oriented programming, single inheritance refers to a type of inheritance where a class inherits from just one parent class. This indicates that there is just one chain of inheritance, with each class having a single parent class, and that all classes ultimately descended from the same base class, which in Python would be the object class.

In Python, single inheritance is implemented using the syntax class
ChildClass(ParentClass):, where ChildClass is the subclass or child class, and ParentClass is the superclass or parent class.Here is an example of single inheritance in Python:

example4.png

In this example, Animal is the parent class, and Dog is the child class. Dog inherit from the Animal class, which means they have access to the name attribute and the make_sound method defined in the parent class.

Dog also have their own unique methods, wag_tail.

Here is an example of how to use these classes:

examples5.png

In this example, Dog have inherited the make_sound method from the parent class, and they have also defined their own methods, wag_tail, and purr. This is an example of code reuse through inheritance.

Multilevel Inheritance


Multilevel inheritance in Python is a type of inheritance where a subclass inherits properties and methods from its parent class, which in turn inherits from its own parent class. This creates a hierarchy of classes, with each level building upon the previous one.

To implement multilevel inheritance in Python, you can create a class hierarchy where each class inherits from the one above it. Here is an example:

example6.png

In this example, we have a base class Animal, which has a speak method that prints "I am an animal". The Dog class inherits from Animal and overrides the speak method to print "I am a dog". Finally, the Labrador class inherits from Dog and overrides the speak method to print "I am a Labrador".

when we create an instance of  each class and  call it is  speak method, we get the following output,

example7.png

as you can see, the Labrador class inherits the speak method from both its parent classes, Dog and Animal, and overrides it with its own implementation.

Hierarchical Inheritance


When there is only one parent class and many children, this sort of inheritance is known as a hierarchical inheritance in Python. This results in a hierarchy of classes with related traits since the child classes inherit the same parent class's attributes and methods.

You can define a base class in Python and numerous derived classes that derive from it to implement hierarchical inheritance. Here is an example:


example8.png

In this illustration, the base class Shape has a draw function that outputs the phrase "Drawing a shape." The draw method is overridden by the Circle and Square classes, which also derive from Shape.

When we create an instance of  each class and call its draw method, we get the following output:


As you can see, each class overrides the draw method with its own implementation while inheriting the colour attribute from the Shape class. As a result, each class exhibits a different behavior. Hierarchical inheritance's fundamental concept is this.

Multiple Inheritance


In Python, a subclass may inherit attributes and methods from a number of parent classes. This is known as multiple inheritances. This makes the subclass more adaptable and versatile by enabling it to draw from a variety of sources for behaviour and functionality.

To implement multiple inheritances in Python, you can create a subclass that inherits from two or more parent classes. Here is an example:

example9.png

In this example, we have two parent classes Person and Employee, which have their own properties and methods. The Manager class inherits from both Person and Employee and overrides the __init__ method to initialize both sets of properties.

When we  create an instance of the  Manager class and call its methods, we get  the  following output:


As you can see, the Manager class inherits properties and methods from both Person and Employee and is able to use them to perform its own tasks. This is the essence of multiple inheritance. 

However, it's important to use multiple inheritance judiciously, as it can make the code more complex and difficult to maintain.

Hybrid Inheritance 


In Python, hybrid inheritance combines multiple inheritance with hierarchical inheritance. A subclass that uses hybrid inheritance derives from a number of parent classes, some of which in turn descended from a single base class. As a result, there are numerous degrees of inheritance and a complicated inheritance structure.

Python allows you to build class hierarchies with several levels of inheritance to achieve hybrid inheritance. Here's an illustration:

In this example, we have a base class Animal and two derived classes Mammal and Bat, which themselves inherit from Animal. We also have two derived classes Dog and FlyingDog, which inherit from Mammal and Bat respectively.

When we create an instance of each class and call its methods, we get the following output:



As you can see, the FlyingDog class inherits properties and methods from both Dog and Bat, which themselves inherit from Mammal, which in turn inherits from Animal. This creates a complex hierarchy of classes but also allows the FlyingDog class to have a wide range of behaviors and functionality. This is the essence of hybrid inheritance.

Polymorphism

The ability to handle objects of various classes as if they belong to the same class is a critical component of object-oriented programming (OOP). Polymorphism is implemented in Python by means of methods and inheritance. An object's capacity to assume various forms is known as polymorphism. Method overloading and overriding are two ways that Python achieves polymorphism.

Method overloading is a typical Python technique for implementing polymorphism. In order to accomplish this, numerous methods with the same name but distinct parameters must be defined in a single class. Python chooses which method to employ based on the arguments supplied to it when an object of that class calls the method.

Another way to implement polymorphism in Python is through method overriding. This involves defining a method in a subclass that has the same name and parameters as a method in its parent class. When an object of the subclass calls the method, Python will use the method defined in the subclass instead of the one in the parent class. Method overriding occurs when a subclass has a method with the same name and parameters as its superclass. When the method is called on an object of the subclass, the subclass method is executed instead of the superclass method. This allows the subclass to provide its own implementation of the method while still retaining the same interface as the superclass.

Here's an  example:


In this example, the Dog class overrides the make_sound method of its superclass, Animal. When the make_sound method is called on an instance of Dog, it executes the Dog class's implementation of the method.

A class that contains many methods with the same name but distinct parameters is said to be method-overloaded. Depending on the kinds of parameters supplied to a method, a class might offer various implementations of the same function thanks to this feature. However, Python does not support method overloading in the conventional sense since it forbids the definition of numerous methods in the same class with the same name but different parameters. Instead, we can implement method overloading using variable or default arguments.

Here is an example using  default arguments:


In this example, the add method of the Math class takes two required arguments, x, and y, and an optional argument, z. If z is provided, it adds all three arguments together; otherwise, it adds only x and y. By providing an optional parameter with a default value, we can achieve a form of method overloading in Python.

Encapsulation

In object-oriented programming, the term "encapsulation" refers to the grouping of data and methods that manipulate that data into a single entity, such as a Python class. Encapsulation enables us to merely present a public interface for interacting with an object and shield its implementation details from the outside world.

Access modifiers, which are keywords that control the visibility and use of class attributes and functions, are used in Python to accomplish encapsulation. Public, protected, and private are the three types of access modifiers available in Python.

Public attributes and methods are those that can be accessed from outside the class. In Python, all attributes and methods are public by default, unless their name begins with a double underscore (__), which makes them private.

Python's concept of "protected members" is a bit misleading because, if needed, they can still be accessed and changed from outside the class. The use of a single underscore, however, typically informs other programmers that a method or attribute should be viewed as protected and not directly accessible from outside the class or its subclasses and should instead be used with caution.

Here's an example of a class with protected member in python:



In this example, the Shape class has two protected attributes (_x and _y) and one protected method (_calculate_area). The Rectangle class is a subclass of Shape and has two additional protected attributes (_width and _height).

Note that the Rectangle class provides a public method called calculate_area that calls the protected method _calculate_area. This allows us to access the protected method from outside the class without directly accessing its name. This is a common pattern for accessing protected members in Python, as it allows us to maintain some degree of encapsulation and avoid exposing implementation details to the outside world.

You can only access private properties and methods from within the class itself. In order to ensure data hiding and encapsulation, private attributes and methods are frequently utilized since they forbid external code from directly altering an object's internal state.

Here's an example of  encapsulation in Python:


In this example, the Car class has three private attributes (__make, __model, and __year) and four public methods (get_make, get_model, get_year, and set_year). The private attributes are accessed and modified only through the public methods, which allows us to control the way the object's state is accessed and manipulated from outside the class. This provides a form of encapsulation that helps to maintain the integrity of the object's internal state and prevent unwanted changes from external code.

Abstraction

Abstraction is a concept in object-oriented programming that refers to the ability to focus on essential features of an object while ignoring non-essential details. Abstraction allows us to model complex systems in a simpler way by identifying key attributes and behaviors that define an object's functionality and hiding the underlying implementation details from the user.

In Python, abstraction is often achieved through the use of abstract classes and interfaces. It is possible to utilize abstract classes as templates for other classes even though they cannot be instantiated directly. 
Abstract classes define abstract methods, which are methods that have no implementation and must be implemented by concrete subclasses. Abstract classes can also define concrete methods that are inherited by their subclasses.


Interfaces are similar to abstract classes but only define abstract methods and do not have any implementation. Interfaces are used to define a set of behaviors that must be implemented by any class that implements the interface.

Here is an illustration of a Python abstract class and interface:



In this example, we define two abstract classes (Animal and Pet) and two concrete subclasses (Dog and Cat). The Animal class defines one abstract method called speak, which must be implemented by any concrete subclass of Animal. The Pet class also defines one abstract method called play, which must be implemented by any concrete subclass of Pet.

The Dog and Cat classes both implement the speak and play methods, which allows them to be used interchangeably with other objects that implement the Animal and Pet interfaces. By using abstraction, we can define a common set of behaviors that all pets should have and allow for different implementations of those behaviors in different types of pets. This provides a flexible and extensible design that can be easily modified and extended as needed.

Python provides yet another method for achieving abstraction. That is accomplished by combining several saved files into one. The user will be able to import files and access some functions through it, but we won't be able to understand how it works. I'll explain.

There is a file 'First.py' in which I'm printing the line "file one":-


and second file named 'Second.py in which I'm printing the line "Second.file":-


And in the third  file named 'third', I'm importing these two files knowing that they will  give the output of:-



In the file named ’Third.py’, I just imported file ‘First.py’ and ‘Second.py’ with the knowledge of that that they will give the output of ‘File One Second File’, but I didn’t know how it will print it. Maybe they will create a method within a class and calling that method in which they have written the statement of ‘File One’. Like this: -


Through the example given above, we can come to the conclusion of that that we would know what a package, a module, or a function does but we won’t know how it does.


That's it for today, guys. If you want to learn more about Python, follow us.


happy learning......

No comments:

Post a Comment