Procedural Approach
In the procedural approach, the stack’s data and the associated logic (functions for pushing and popping) are separate. Below is an example where the stack is represented as a simple list, and helper functions manipulate it.In this implementation, the global
stack variable can be accessed and modified from anywhere in your code, which can lead to unintended side effects. For multiple stacks, additional functions must be created, reducing reusability.Object-Oriented Approach
The object-oriented method encapsulates both data and behavior within a class, promoting modularity and data protection. We begin by defining aStack class with an initializer that confirms the creation of a new stack instance.
stack_list) is public, offering direct access:
Although a public attribute is simple to implement, it compromises encapsulation. To protect the internal data structure, converting it to a private attribute is recommended.
stack_list to a private attribute by prefixing it with two underscores. Attempting to access this attribute externally will raise an error:
push and pop methods to the Stack class for manipulating the internal stack:
Stack class maintain independent data, providing a scalable solution for handling multiple stacks.
Extending the Stack Class with Inheritance
Inheritance allows you to extend the functionality of a base class without modifying it. Consider a scenario where you need to track the cumulative sum of the elements in the stack. Instead of altering the originalStack class, you can create a subclass AddingStack that inherents from Stack and adds new behavior.
In the subclass:
- The constructor calls the base class constructor using
super().__init__(). - The
pushmethod is overridden to update the cumulative sum before invoking the base class method. - The
popmethod is overridden to subtract the popped value from the cumulative sum. - A new method
get_sumis introduced to retrieve the current sum.
If a subclass does not define its own constructor, it automatically inherits the constructor from its superclass. In cases where no additional behavior is required, you can simply use the
pass keyword to inherit all functionalities without modification.