Learn Object-Oriented Programming(OOP) In Minutes
By: Kolawole Precious
Tags: Python Programming, Object Oriented, Software Architecture, Data Science, Code Improvement

Understanding the most natural and pragmatic approach. Once you get a hang of it, implement real-world problems by delving deeper into Python programming.

Most times, your coding sequence of steps have been perambulating around data analysis, preprocessing, visualization, modeling, all these are part of thinking routinely.

To understand the intuitions behind this, let’s take, for example, the Nigeria’s system of education. We have a sequence of pre-primary>>primary>>secondary>> tertiary. This sequential viewpoint works if we are talking about maybe Nigeria as a country alone. However, if this is about continents and regions, you’d have to think about thousands of countries' educational systems all over the world. Mapping out a sequence of actions for each country may get unsustainable, regardless, you’d have to start thinking about patterns for all continents.

This ideology works hand in hand with codes, more data warrants more steps and more functionalities.

In short, Object-Oriented Programming(OOP) is a collection of objects(data) and patterns of their interactions. OOP focuses on the thinking process, implementation of what the developer wants to manipulate rather than the logic required to manipulate them. Code scalability, efficiency, reusability, information protection, easy debugging are all benefits of OOP.

Object-Oriented Programming Languages include;

Java

C++

Python

C#

JavaScript

R, PHP, Ruby, Swift, Dart, Scala, Kotlin, Matlab, e.t.c

In this article, we are channeling our energy to OOP in Python.

Objects in Python

Almost everything in Python is an object, with its properties and methods forming the Class.

class in python

You can call type() on any Python object to get its class. The dir function helps us to know the methods and attributes attached to the str class.

methods and attributes in python

Some other class examples can be seen below.

object with classes

Strengths of OOP

Classes

Objects

Attributes

Methods

Classes

Classes are the real strength of utilizing OOP known as user-defined data types. It is the blueprints for objects which describe the possible states and behaviors that every object of a certain type could have. If I tell a friend, saying,

“Every one of my users will possess a name, an email, and will be able to sign in to the website”, yo! I just created a class!

creating your first class

This is our first class. The body of the class is left empty for now.

new instance

Here, we create a new instance of the User class. In other words, we instantiate the User class. The usd is a reference to our new object. Meaning, usd is an instance object of our User class.

Objects as a Data Structure

An object is a data field that has a unique state and behavior. It can be a combination of variables, functions, data structures.

Object= State+ Behavior

State, in the sense, that, name and email. Behavior, as in, clicking the sign-in option of a page.

Attributes

In layman English, an attribute is a quality or characteristic attached to a type. Similarly in Python, they are created by assignment and defined in the class template as information that is stored. Individual objects contain data that is stored in the attribute field. For example, each user of a website can be identified differently based on the names and email address(es) provided before making a sign-in.

Attributes = Variables >>> Obj.my_attributes

Attributes in Python are often represented as variables like numbers, strings, lists, tuples, dictionary.

class with attributes

Methods

Methods perform actions; methods return information about an object or update an object’s data. The method’s code is always defined in the class definition as behaviors that are represented by functions. From the User example, The sign-in method is defined in the User class and the sign-in() is called on the object usd to get the output.

example of method

By following the code snippets above, you should notice the self word being called severally. Don’t get confused, explanation in a bit!

What is Self?

Self stands for future objects.

Objects of a class don’t yet exist when a class is being defined. But we often need a way to refer to the data of a particular object within the class definition. It is a stand-in for a particular object within a class definition, also a reference to the current instance of the class, and it’s used to access variables that belong to the class.

Still, it’s neither a keyword nor special name but a conventional name which can be replaced with any other words like “kitty”, “ iris”, e.t.c based on the programmer’s intent as long as they’re used consistently without replacement.

Note: The self parameter should be the first argument of the regular instance method. Nevertheless, always keep self as self.

The snippet below is a reference in case you’re still not familiar with how to differentiate between all the four strengths of OOP. Here is a rough hand sketch pointing to each of them.

check each directed arrows

The Python Object Initializer

While checking other developer’s codes or maybe library documentation, you must have come across the __init__ constructor in which many beginners are puzzled about its purpose and how it is being used. The __init__() is called The Constructor of a Class. It is called automatically right after the object has been created.

This is a very sustainable approach if your class contains a lot of data. It allows you to add data to an object when creating it.

In the code snippet of the Attribute subheading, we defined the my_name attribute in the set_name method of the class User, and then calling the set_name method will add Kolawole Precious attribute to the usd object, same as the set_email method. Alternatively, everything can therefore be defined under the constructor.

init constructor

Using the __init__ constructor, we hereby ascertained that our code is more maintainable, readable, and well organized.

Four Basic Principles of OOP

principles of OOP

Inheritance

Encapsulation

Polymorphism

Abstraction

Inheritance

It refers to defining a new class with little or no modification of an existing class. Inheritance inherits all methods and properties from another class. It allows code reusability, allows classes to inherit features of other classes.

New Class Functionality = Old Class Functionality + extra

You know, for example, Cancer extends attributes and functionalities to Breast, Cervical, Lung, Skin Cancers respectively. Meaning, all Breast Cancers are Cancer but all Cancers are not Breast Cancer. Inheritance represents “is a” relationship.

example code of inheritance

Here, we put the Cancer(Parent) class in a round bracket after the name of the BreastCancer(child) class. The Cancer class is defined and then a seemingly empty Breast Cancer class inherited from it. Breast Cancer is seen to have all attributes and functions of the general Cancer class.

We created an object b_can even though we did not define a constructor. Surprisingly, we can access the __color and _nucleon attribute from the Breast Cancer class even though these features are not defined in the new class.

parent and child differentiation

The parent class is also known as superclass, ancestor, or base class. A child class can also be called a derived class, descendant, or extended class.

Encapsulation__Adding Functionalities to Inheritance

Now, we can see that both class and the child class we created possess the same functionalities. Here is how to add more functionalities to our child class by adding a constructor specifically for Breast Cancer making it different from the Cancer class.

outputs after adding more functionalities

Owning from the code above, we get to Encapsulation in OOP. We’ve created the Cancer Class with some attributes and methods as well as the BreastCancer Child Class with its. However, if we simply can change the properties of the Cancer class just by the reference of the object, then the attributes lose the information by which it was initially initialized.

Let’s say we have initially created a Cancer class with a black color attribute. Any user with the instance of the object of the BreastCancer can change this color to orange or blue by simply referring to the attribute. To avoid this, we enclosed the attributes in the getters, setters method. We can see from the output snippet that each of the classes retained its attributes.

super() seen under the child class function helps to specifically call the Parent class method which has been overridden in the child class, from the child class. In case you need to call a method or attribute from a specific parent class, use super().

We ought to have noticed as well, the double underscores(__) preceding each of the attributes. They are used for private variables. According to Python documentation − If your class is intended to have child classes, and there are attributes you don’t want the child classes to use, consider naming them with double leading and not more than one trailing underscore.

Python interpreter rewrites the attribute name to avoid naming conflicts in child classes and changes the name of the variable in a way that makes it harder to create collisions when the class is extended later.

Benefits Of Encapsulation

It helps us enclose the initialization and retrieval of the attributes in methods.

It helps to restrain unnecessary changes.

The getters and setters give us thorough control in getting and setting values to the attributes.

Polymorphism

In a literal sense, polymorphism is the ability to assume different shapes and forms. In Python, it means a variable, function, or object can take on multiple forms. While in OOP, polymorphism allows us to define methods in both the child class and parent class with the same name. The work of polymorphism can be addressed in two different ways;

Method Overriding

Method Overloading

Method Overriding

This is used in situations where a method inherited by a child class from a parent class doesn’t fit in the child's class. Meaning, we’d have to re-implement the method in the child class.

method overriding example

Here, the parent class Dog has the unique ability to bark with a louder sound. Child class Puppy can make sounds as well but a less loud one. Significantly, the method inherited from the parent class wouldn’t fit in the child class, so a different implementation is provided for the child class.

Meanwhile, each of the methods is called based on the type of object used in calling it. When Puppy class object py is used to call an overridden method bark() then the Puppy class version of the method HOWL is printed. But if the Dog class object dg with the method bark() is called, WOOF is printed out.

Method Overloading

Overloading, in programming, refers to the ability of a method to behave in different ways depending on the parameters that are passed to the method. Here, we will see how we can perform method overloading in Python.

Method or function may have the same name, but a different number of parameters passed into the method. Different outputs are going to be gotten depending on the number of parameters passed in.

method with parameters

Above, we see how the bark() is set to the object with or without parameters to get different outputs.

Regardless, true method overloading is utilized in other programming languages and not seemingly Python.

Abstraction

Abstraction means hiding the complexity or internal implementation from the users.

Simple codes are used to represent complexity.

Hide complex details from the users.

A real-life example is the details of how the engine transmission and braking systems of a car works whose execution and automation are not known to the people driving the car. A car is not seen as different individual parts but a well-defined object with its distinct behaviors. Abstraction in OOP is achieved by using abstract classes and methods.

An abstract class provides incomplete functionality and contains one or more abstract methods. Abstract methods don’t have any implementation but the child classes are left to provide the implementation for the abstract methods.

To declare an abstract class, we first need to import the abc class from the ABC module.

import ABC

abstraction.py output

User is an abstract class that inherits from the ABC class from the abc module, Cash and Transfer child classes inheriting from the User class with both having their clearance() plus receipt( ) methods which are the only things visible to the users. However, when clearance() is invoked in the object of each of the child classes with an amount parameter passed in, the print statement of the child classes get displayed. These definitions are concealed from the users.

Before we bade each other goodbye, let’s quickly brush through this.

Design Techniques Recommended for OOP Codes

Class names are to start with capital letters. If a class name contains more than one word, each should begin with a capital letter e.g ClassName . They’re seen to be nouns.

. They’re seen to be nouns. The pattern of functions and loops are expected. Indentation as proper in the line of codes that come after the class.

The definition of a method must start with the def keyword.

keyword. Method names must begin with lowercase letters. If it’s more than one word, it should either have a hyphen (_) in between the words e.g method_name , or every word after the first begins with a capital letter e.g methodName() .

in between the words e.g , or every word after the first begins with a capital letter e.g . Parameters should be as clear as possible indicating its purpose and existence.

Names should never start with special characters e.g &, %, _, €.

A string literal (‘’’) and not other type of expressions occurring immediately after a class or function at the top before any other statement is a docstring. This helps users understand the intuitions behind the classes, methods, and attributes. It can be seen as output by calling the python built-in help function on the specific class or method. In a scenario where many developers contribute to a certain project, it’s a way to pass information about classes and methods created to help others understand each of their written codes and ensure code reusability.

docstrings and help function