Object Oriented Thinking

Arvind Hari
7 min readMay 29, 2021

An Intro to OOPs

Image Source: https://codezen.io/

Considering the rise in usage of data science pan industries irrespective of the domain, the audience targeting to learn basics of programming to inherit data science and ML in their daily life is increasing. This article aims at throwing some light on the ideology of ‘What is Object Oriented approach’, understanding its basic deployment using Python.

I myself being a core MechE, I have myself endured quite a bit of challenges understanding programming. In this article, I have stressed on the aspects of “Objective Oriented” approach so that we can absorb this and exploit it for our daily lives.

As big and scary the name is, the concept is as easy (but vast) to understand and implement… All we need here is to understand the purpose of OOP

A warm welcome to all to the world of OOP.

Until now we were wandering around in the world of SCRIPTING, where the code is written directly without any representation of the real world entities and their inter-relationships. But now, we would be doing things in a more realistic way, the PYTHON way. Luckily we are working with Python which supports scripting as well OOPs.

Ideology behind OOP

Before we start, let us try to answer ourselves, what comes to our mind when we hear the cars, laptops, animals, sports etc.

For example, as soon as I hear CAR, my mind pictures a closed body with 4 wheels, 4 doors, corresponding windows with an engine that can move. This is a generic descriptions of what a car is, what are its attributes, what are its functions etc. However, different brands, different models, different makes, different versions of car exists which have their own inherent differences of all the attributes mentioned above. But the features (feature names, a wheel is generally called a wheel regardless of the car under consideration) of a car remains same. In addition to the features, cars have certain behaviors like it can move either in forward or backward direction at a time, it can run with or without AC, impact of AC on mileage, max steering capacity based on speed or something.

In the example above, CAR is the class of objects while number of doors, number of wheels, brand etc. are the features of this class object. Similarly, features of different cars can be defined using the features of a common car by just updating the corresponding values. The behaviors of the car is defined as the methods of the class object.

In a similar way, analogically, we can construct our program in a fashion that can group certain similar objects (objects with similar features and methods) under a specific category called a CLASS. For example, when 2 variables ‘a’ and ‘b’ are assigned values ‘hey’ and ‘hello’ respectively, which are strings, python interprets this as two different objects of the string class. This is exactly why we get error while typecasting strings to numerical as strings do not have the inherent behavior or method to apply this transformation. These are inbuilt classes, we can also define user defined classes to meet our application requirements.

A class is a blueprint for how something should be defined. It doesn’t actually contain any data. While the class is the blueprint, an instance is an object that is built from a class and contains real data. An instance of the CAR class is not a blueprint anymore. It’s an actual CAR with attributes like cost, brand mileage etc.

In summary, the idea behind OOP is to capture the features and behaviors of an object under the same software object called CLASS. Put another way, object-oriented programming is an approach for modeling concrete, real-world things, like cars, as well as relations between things, like companies and employees, students and teachers, and so on. OOP models real-world entities as software objects that have some data associated with them and can perform certain functions.

Advantage of OOP over Scripting

A few advantages to start with include, it improves the reusability of the code, supports modularity, makes the code more representative of real world, allows definition of relations between multiple entities.

Well, these are the same words we used while defining functions, then during module creation and now with OOP, it just keeps getting better and better. When we used functions, we were automating stuff within the same code, when the same functions were defined as modules, it could be used in any code, but now when we use OOPs, the whole bunch of feature variables and their corresponding functionalities or behaviors can be described using a single object. Different objects with similar features can use the features and methods from the common class already defined.

The verbosity ends for now, let us jump into a simple code snippets to understand what a class is, what its attributes and methods are. By the end of this article, we will try to understand how relations between two objects can be established using OOPs.

Defining Multiple Objects for the same class

As we discussed, the idea of using objects is to group similar instances under the same class. In the prev example, we defined the attributes of Audi Q7 (random values used for the sake of understanding attributes)

In a same way, different objects with CAR class (diff arguments) can be assigned to new objects

Let us try to define Tata Nano and Toyota Fortuner (random values used for the sake of understanding attributes

Object Definition

Did you notice in the code above, three different cars, with same attributes could be created using different car objects but same attributes of the CAR class. Well, thanks to OOPs, our code looks much more modular and real-world oriented. All the attributes defined within the init() are called as Instance attributes as it can take different for different class objects. A class attribute can be defined outside of init(), this will have the same value for all the class instances created.

Remember that custom objects are mutable by default. An object is mutable if it can be altered dynamically.

Next, it is time to understand behavioral definition (methods definition) and its access.

Class Object Description

Whenever we just call the class identifier in the main code, a new instance of the class is created at a new memory location. This happens regardless of whether the instance is assigned to a new variable or not. The output usually shows the name of the class when class is called along with the memory address. But this information is not very helpful for the user.

We can use another inbuilt function __str__() which can be used to override the output when a class is called. We can customize the output using __str__(). Such inbuilt functions starting and ending with double underscores are called as dunder functions.

Describing Objects without __str__( )
Object Description CODE using __str__( )
Object Description Output using __str__( )

Comments on ‘self’

What does a ‘self’ variable do

All the attributes initialised in the init() and the methods created are local and specific to the class within which they are defined. These methods and attributes have meaning only in the presence of the corresponding class. ‘self’ is a pointer that just refers to the class name by default at the time of initialisation. It is a positional argument.

The first argument passed at the time of class call or method call corresponds to the variable next to the ‘self’ pointer in the init() or method definition.

What happens if we miss ‘self’

‘self’ is not a keyword, it is just a positional argument, representing the pointer. In case, self definition is missed, python interpreter will consider the first variable defined in the parameter list as the pointer referring to the class. This will mess the downstream arguments’ positional assignments. We do not want this to occur.

Hence, we must always ensure a dedicated pointer is defined as the first position within all the methods of the class (dunder and user defined methods). This pointer name is local to the method, each method can have its own local pointer name. But when the attributes of the class are called from the specific method, local pointer name should be correspondingly used in the dot notation.

Best Practice

However, as a best practice, ‘self’ should be used across all the methods.

Example below recreates the car_3 class with replacements for the ‘self’ pointer name in all the methods (dunder and user def.). I am repeating, this is not advised, always use ‘self’.

Demonstration of varying pointer names instead of ‘self’

With this, I am concluding the introduction to object oriented appraoch. See you all with an article on OOPs concepts

The jupyter notebook used has been checked into to my Github profile

JUPUYTER notebook with Intro to OOPs

https://github.com/arvindhhp/PyPro_ahhp/blob/main/Part_014_OOP_Introduction.ipynb

Github Profile:

--

--