The 3 pillars of the OOP
By: Sech Rueda
Tags: Object Oriented, Oop Concepts, Python, Programming Languages

Few days ago i had a Python developer job interview and besides studying the syntax of the language i thought it was a pretty good idea to take a look again on the “3 pillars of the Object-oriented-programming”. That in other words just means what makes an OOP language an OOP language.

In online resources you might not find just 3 but 4 or even 5 and they can be called in different ways but the definition remains the same.

That's okay, but in my opinion we can resume all in just the ones i will be explaining on this post.

I like to understand things really from the root, so let's take a quick look of what OOP is.

From wikipedia definition:

“Object-oriented programming (OOP) is a programming paradigm based on the concept of “objects”, which can contain data, in the form of fields (often known as attributes or properties), and code, in the form of procedures (often known as methods).”

Object-oriented languages include Java, C++, C#, Python, PHP, JavaScript, Ruby, Perl and many more.

Now, they are some specific features that a programming language must be able to provide in order to be called an object oriented language. As i told before i will resume them in this 3:

Encapsulation

Specialization

Polymorphism

From this on i will be attaching examples in Python language code because it is the one that i like the most so far. Don't worry, of course the concepts remains for every other object oriented language and also based on the hacker.io most popular languages statistics Python is not doing it bad at all!.

Encapsulation

Every class you define should be fully encapsulated, that means that every class defined should contain the whole class data and the functions to manipulate that data.

From the example on orreilly:

“If you create an Employee object, that Employee object should fully define all there is to know, from the perspective of your program, about each Employee.

You do not, typically, want to have one class that defines the Employee’s work information, and a second, unrelated class that defines the Employee’s contact information. Instead, you want to encapsulate all this information inside the Employee class, perhaps by aggregating the contact information as a member of the Employee class.”

In our example we will bring a “Person” class:

class Person():

''' Person class ''' def __init__(self, name='Noname', age=0, gender='None', sexuality='None', religion='None'):

'''Initialize person'''

self.__name = name

self.__age = age

self.__gender = gender

self.__sexuality = sexuality

self.__religion = religion def get_name(self):

'''Return person name'''

return self.__name def set_name(self, name):

'''Set person age'''

self.__name = name

return self.__name def get_age(self):

'''Return person age'''

return self.__age def set_age(self, n):

'''Set person age'''

self.__age = n

return self.__age def get_gender(self):

'''Return person gender'''

return self.__gender def set_gen(self, gen):

'''Set person age'''

self.__gender = gen

return self.__gender def get_sexuality(self):

'''Return person sexuality'''

return self.__sexuality def set_sex(self, sex):

'''Set person sexuality'''

self.__sexuality = sex

return self.__sexuality def get_religion(self):

'''Return person religion'''

return self.__religion def set_rel(self, rel):

'''Set person rel'''

self.__religion = rel

return self.__religion

Let’s say that this is all the information and data required from a person and we are going to assume that we will just require to pull out and update this information. We can note then that all the data and functions (methods) to handle that data are inside the definition of the class itself. We then can say this class is fully encapsulated.

Specialization

Specialization allows you to establish hierarchical relationships among your classes. That means that one can define a class to be derived from another existing class. By doing this the “child” class will inherit the characteristics of the “parent” class.

This is something pretty useful to avoid unnecessary duplicated code.

We are going to create a “Teacher” class to understand this better.

Think about it: a teacher is a person itself right?

By telling this i want to highlight that there is not necessity to duplicate code in order to return or set a teacher’s information like name, age or any other attribute that is already existing in the person class.

This is where inheritance is useful for!

class Teacher(Person):

'''Teacher class inherits from Person class''' def __init__(self, knowledge, experience):

'''Initializing teacher'''

super().__init__()

self.__knowledge = knowledge

self.__experience = experience def get_knowledge(self):

'''Return teacher knowledge'''

return self.__knowledge def set_knowledge(self, know):

'''Set teacher knowledge'''

self.__knowledge = know

return self.__knowledge def get_experience(self):

'''Return teacher experience'''

return self.__experience def set_experience(self, exp):

'''Set teacher experience'''

self.__experience = exp

return self.__experience

You see?…Using this principle we don’t have to redefine the same attributes and methods for the Teacher class but only the ones that the Teacher class will specially have.

To call the Parent class methods on this one we used the super() builtin. If you want to know more about it click here.

Polymorphism

But.. just a moment. What if the teacher doesn't want to share some private information as his/her religion or sexuality?.

We should totally respect this decision right?

The correct thing to do would be to ask the teacher first if he/she want this information to be release don’t you think?

That being state, we know now that the get_religion() method has to bee different from the Person class one.

And this is where the polymorphism plays its role:

From overig.com:

“In literal sense, Polymorphism means the ability to take various forms. In Python, Polymorphism allows us to define methods in the child class with the same name as defined in their parent class.

As we know, a child class inherits all the methods from the parent class. However, you will encounter situations where the method inherited from the parent class doesn’t quite fit into the child class. In such cases, you will have to re-implement method in the child class. This process is known as Method Overriding.”

Overriding get_religion() method for Teacher class:

def get_religion(self):

'''

Return teacher religion

if he/she wants to

''' print('Do you want to share this?')

answer = input() if answer == 'yes':

print('Thank you for your consent')

return (super().get_religion()) if answer == 'no':

print('Sorry person doesn't want to share religion')

return else:

print('Answer needs to be yes or no')

return

Make sense right?

Let’s make a little test:

man = Person('sech', 34, 'Male', 'Hetero', 'Christian')

print('Person religion is: ', man.get_religion()) Teacher_1 = Teacher('Math', 4)

Teacher_1.set_rel('Catolic')

print('Teacher Religion is: ', Teacher_1.get_religion())

Output:

Person religion is: Christian

Do you want to share this?

yes

Thank you for your consent

Teacher Religion is: Catolic

If you want to have the code to make your own tests you are welcome here.

Hope this have been helpful for you somehow.