Louiza Mak
Posted on May 20, 2024
Okay, maybe it wasn't really my first foray into OOP, but I don't think I'm going to count the couple pages of "Java: A Beginner's Guide" I read about a year ago. Or the one-off C++ class I ended up dropping after a few months because I was a Biology student and I really thought I had no business being in there. A comp sci minor was just not in the cards at that time. For the most part, I've stuck to my side of the road since I began my coding journey and learned as much JavaScript a beginner could before hopping into a bootcamp. It's where I began building my foundation and learning the fundamentals of what it is to think and breathe like a programmer. It's where I was most comfortable and where I was most confident. I breezed through the lessons, waded through a whole section of React, and learned that React was infinitely better. And, not to toot my own horn, I was pretty decent at it - at least according to my bootcamp requirements. I was feeling great. And then, I was hit with Python.
The spaces, the indentations, the lack of curly brackets. I thought I was going to lose my mind. Reading Python was like reading a run-on sentence the length of a paragraph. Although the language syntax bore some resemblance to JavaScript, which I grew to love, I initially struggled to adjust. And after all that adjusting, I was faced with another, larger hurdle. Learning about and using Classes.
Python is an object-oriented programming language, as I'm sure most readers here already know. But if you're a beginner like me, it's not explicitly clear how this language differs to JavaScript at a glance. Is it because JavaScript doesn't have objects? Then what was that data type I learned about encompassed in fancy curly brackets? Or is it because Python focuses on this aforementioned data type as its main data structure? Because Python is "object"-oriented, get it? I had a lot of questions and apprehension coming into this new language but I also wanted to keep an open-mind. So here's what I learned for the beginners in the back.
Objects and Classes
A class is a code template to create objects in Python. It's made up of methods and variables and is used to support inheritance by reducing redundant code. I'll touch on inheritance later on but all you have to know for now is that classes are extremely important in Python because we use them to create objects.
Everything in Python is an object. And I mean, everything. Integers, strings, floating point numbers, arrays and even dictionaries, are all objects that are built-in. Objects in Python are instances of a particular class that contain its own data and functions to manipulate that data, almost like its own mini-program.
To create a class, we use the class
keyword:
And to create an object, you call the class:
Beyond objects and classes, a lot of people will also throw key terms to memorize at you when you first pick up an OOP language. Abstraction, Polymorphism, Encapsulation, and Inheritance. These concepts are vital to understanding why most major software development companies prefer OOP languages. And thankfully, the couple pages of "Java: A Beginner's Guide" that I read summarized what each term means in the scope of programming.
Abstraction
Goal: Simplifying Complexity
Abstraction is the process of hiding the complex implementation details of a system and exposing only the necessary parts. It鈥檚 like driving a car; you don鈥檛 need to understand how the engine works to drive it. You only interact with the steering wheel, pedals, and dashboard.
In programming, abstraction allows you to define complex operations in simple terms. For example, let's take this car analogy further and consider a Car class in a program:
Here, start_engine
, drive
, and stop_engine
are high-level methods that hide the intricate details of how a car starts, drives, and stops. This abstraction makes the Car class easier to use without requiring the user to understand its internal workings as users will only need to call the class along with its method. For example: Car.start_engine()
and Car.stop_engine()
.
Inheritance
Goal: Reusing Code
Inheritance allows a class to inherit properties and methods from another class. This promotes reusing code and establishes a natural hierarchy between classes.
To continue with the car analogy: imagine you have a base class Vehicle and you want to create a Car class and a Bike class. Instead of rewriting common functionality, you can inherit them from Vehicle:
Here, Car and Bike inherit the start
method and other properties from Vehicle, making the codebase more maintainable and DRY (Don't Repeat Yourself). In addition, we can utilize the super
method to avoid even more redundancy.
The super
method returns a temporary object of the parent class and it's typically used to initialize parent class attributes or invoke parent class methods. In the example above, it is used to call the __init__
method from the Vehicle class to make sure the make
and model
attributes are properly initialized without redundant code. This also allows the Vehicle class's __init__
method to be modified without needing to also update its dependent classes.
Encapsulation
Goal: Protecting Data
Encapsulation is all about bundling the data and methods that operate on the data into a single unit, i.e., a class, and restricting access to some of the object's components. This protects the integrity of the data and prevents unintended interference.
Let's use a new analogy and imagine a Store class. We could create many classes that inherit properties and methods from it but there is one class's data that we want to ensure the integrity of - the CashRegister Class. In the CashRegister class, we want to restrict direct access to the total balance:
Above, __balance
is a private attribute that can only be accessed with the class. The following methods deposit
, withdraw
, and get_balance
provide controlled access to update and view the balance. This ensures the register's data integrity and prevents unintended interference.
Polymorphism
Goal: Code Flexibility
Polymorphism allows objects of different classes to be treated as objects of a common super class, something we've touched on throughout this blog. It enables one interface to be used for a general class of actions, making the code more flexible and easier to extend.
For example, consider an app that processes payments from different sources such as credit cards, PayPal, and Bitcoin. We can define a common interface in a superclass and implement specific details in the subclasses:
In this example, process_payment
is defined in the superclass Payment and implemented in each subclass. The process_transaction
function can process any payment method, demonstrating polymorphism.
Conclusion
Understanding objects and classes is vital to writing efficient, reusable, and simplified code. It is part of the core foundations needed to excel in Python and understanding other OOP languages. The principles of Abstraction, Inheritance, Encapsulation, and Polymorphism are equally essential for creating robust, flexible, and maintainable software. They enable developers to write code that is not only easier to understand but also easier to modify and extend. By mastering these concepts, even if you have to struggle through it like I did, you can leverage the full power of Object-Oriented Programming to build sophisticated and scalable applications. And at the end of the day, isn't that what we all want to achieve? I know this isn't a thick, well-researched, and well-written book like "Java: A Beginner's Guide", but I hope that this can help you in beginning your own Python journey.
Posted on May 20, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.