Python OOP Tutorial – 1. Objects in OOP

Initially it was procedural programing, which just uses methods or functions that do specific tasks. In procedural programing program logic flow linear, from start to end, sometime there point from functions that go to the program end. When programs become complex and there are many relationships between components working and maintaining procedural programs become difficult. From that reason appear object-oriented programing.

OOP is necessary especially when code becomes too complex, the code logic becomes too bushy. If we need to write a program for a car, imagine this have a logic for maintaining direction, for engine use, for lights, etc.  When writing programs for complex systems the solution is to identify entities and define classes for them. For each entity we have attributes and for those we use in classes variables. Each entity has specific functionalities and those correspond in classes to methods or functions. That is in simple mode OOP idea, obviously things are more complex, OOP means more like constructors, inheritance, interfaces, etc. We will discuss those later during tutorial.  Click here  for an exhaustive description of OOP. 

Let's take in this tutorial an example related to horticulture plants. What are some attributes of those plants? Some attributes are: lifetime, biological characteristics, color, type of seed, type of root, etc. What are some methods? Let's put here: germination, greeding, pollination, fruit ripening. The class is the blueprint that model OOP paradigm. First, we need to define the class. Then generate based on that many more objects, "instantiating" that class.


Simple example of class definition in python:

class Plant:

    def __init__(self, lifetime, biological_characteristic, fruit_weight):

        self.lifetime = lifetime

        self.biological_characteristic = biological_characteristic

        self.fruit_weight = fruit_weight

    def printplant(self):

        print(self.lifetime, self.biological_characteristic, self.fruit_weight)



mybrocolly = Plant("biennial", "vegetable", 250)

apple1 = Plant("perennial", "tree", 70)


print("Brocolly is a " + mybrocolly.lifetime + " plant")

print("Apple is a " + apple1.biological_characteristic)

mybrocolly.printplant()


#output 

Brocolly is a biennial plant

Apple is a tree

biennial vegetable 250


Explanation about above: 


The class name is Plant. It begin with capital letter ("P"). If class name is composed from multiple words, each first letter of the words should be in capital for example if we desire to name class "plantblueprint" correct name should be "PlantBlueprint", this  notation is known as "Pascal case" Class has three attributes: lifetime, biological_characteristic and fruit_weight.

__init__ is a special class method, the class constructor, inside it we initialize class attributes. After class definition we create two objects: 

mybrocolly using  line -> mybrocolly=Plant("biennial", "vegetable", 250) 

apple1 using line -> apple1=Plant("perennial", "tree", 70) 

In both cases mybrocolly and apple1 are objects and are created from the same "blueprint", class Plant

Observation: fruit_weight is in grams


Now some explanation about how __init__ (in some sources named constructor) works. When we run mybrocolly=Plant("biennial", "vegetable", 250)  constructor __init__ is appealed and it initialize object attributes, there will be: 

lifetime="biennial" which is realized by self.lifetime = lifetime constructor instruction 

biological_characteristic="vegetable" which is realized by  self.biological_characteristic = biological_characteristic

fruit_weight = 250 which is realized by  self.fruit_weight = fruit_weight


To access lifetime attribute of the mybrocolly object we used mybrocolly.lifetime, means in general to access atribute we 

use "objectname.attributename". Similar to acccess apple1 biological_characteristic attribute we used apple1.biological_characteristic.