What is OOP?

OOP stands for Object-Oriented Programming. It is a set of rules that allows you to create objects. It saves you time by helping you write less redundant code using a class. Objects can be people, animals, cars, etc...

A class is a user defined data type that serves as a template. Think of it as a specially-shaped cookie cutter. When creating a class, it is standard to type the class name in CamelCase. Before we dive into coding, let's first talk about the four important principles of OOP.

Inheritance

Inheritance is when a child class derives from a parent class and has access to all the parent members.

Abstraction

Abstraction is when you hide complex logic behind methods that makes it look simple - like an interface in Java and C# programming languages.

Encapsulation

Encapsulation is the idea of making a method or member private, preventing anyone and anything from modifying the data directly.

Polymorphism

Polymorphism is a term derived from the greek language. It means something that takes on multiple forms. In the programming realm, it describes the ability of an object or a method to have many forms.

OOP in Python

In this walkthrough, I will assume you already have standard knowledge of the Python programming language. When creating and naming a class, remember that the class name needs to be in CamelCase:

Next we are going to build a constructor for our class. A constructor is a special type method that is invoked when an object of a class is created. In Python, the constructor needs to be built first before we can create members and methods, versus C++ where we first have to establish Access Modifiers. We will tackle Python's constructor and class building process first.

__init__ is a special method known as a constructor. It is used to initialize the members/attributes within our class. This is a required step in order to properly create objects with the class later on in the scope. Next, let's give our class an attribute/member, color. In python, its best practice to create your members in lowercase.

Next we are going to use the keyword self to point to the color attribute. Self simply means this instance. Below we are saying, this instance of color = the color the user inputs, because each time an object is created, it will have its own instance. We will see this in action once we create objects with our class.

Now that we have constructed our class in Python, we can give it methods. Methods are functions within the scope of a class. These methods can be used to give functionality to attributes/members within the class. Below, we will create a method called Flavor that prints a flavor based on the color the user inputs. Methods within a class typically take in the self keyword as well.

Now that we have a fully constructed class with a method, let's build our objects. We will name them customer_one and customer_two and then we are going to initialize our class and take in an input from each customer.

customer_one requested a yellow-colored cookie, and customer_two requested a gold-colored cookie. If we look at our method, we only have three colors: brown, red, and yellow. Any color outside of our inventory we simply do not have. Now, let's validate our colors to the customers by calling our flavor() method, which we can now do in the public scope because we have initialized our class when building our objects.

We can now run our code. We were able to process both customer_one and customer_two requests and responded based on our Flavor() method. customer_one requested a butter cookie and customer_two requested a cookie we do not have. Notice how both objects(customers) were able to request their own cookie and get two separate responses. This (no pun intended) is all thanks to the self keyword, as self = this instance, and each object had their own instance.

OOP in C++

In C++, building a class is a bit different from Python. In this walkthrough, I will assume you already have standard knowledge of the C++ programming language. When creating and naming a class, remember that the class name needs to be CamelCase, this is standard across most programming languages:

Next, let's create our Access modifiers. Unlike in Python, to access our attributes/members, we need to establish access modifiers. In the rest of this walkthrough, I will be abbreviating access modifier as aM - this isn't standard. There are currently three aMs: private, public, and protected.

private means that all attributes within your class will not be accessible, which is the default, even if we do not establish members within the private scope.

public means that all attributes within your class will be accessible outside of your class.

protected deals more with inheritance. If we set members within the protected scope, only the classes that derive from the parent class can access the protected members. Let's create our members/attributes. We will create Color.

Unlike in Python, it is conventional that our members'/attributes' names start with a capitalized character. Next, we are going to build our constructor. In C++ there are two types of constructors, one that the developer builds and the other that the compiler generates on default. If we do not build a constructor, the compiler will construct our objects with empty or random values. Also, the constructor MUST have the same exact name as the class.

In C++, to allow the constructor to create objects from the class, we would first need to give the constructor parameters. The parameters aren't the members of the class, but instead are instances of the members. Above, we have color and Color. The Color is the member of this class and the color is an instance of the Color member. In Python, we simply use self to differentiate the attribute/member from the instance. Now that we have our constructor setup with our member, let's create a method called Flavor(). This method, like in the Python method, will validate if the customer is requesting a flavor we have in our factory by asking for a color.

Now that we finally have our constructor, members, and method, we can begin creating objects within our main scope. We will create two customer objects that will request cookies based on color.

With the example above, we created our objects. Beforehand, we had to specify a type. Just like with everything in C++, a type is required when creating objects and variables. Our type in this case would be our class name for our objects. Next, we initialized the constructor by referencing it with our objects(customers). In this case, customer_one requested a red cookie and customer_two requested a white cookie. We will now validate the colors with our Flavor() method within our main scope and see if we have the cookies the customers are requesting.

We were able to process the requests and saw that customer_one requested a strawberry cookie and customer_two requested a cookie we did not have.

Applying OOP Principles

In this section, we are going to use Object-Oriented Programming Principles within our CookieFactory class. I will demonstrate the principle first and then explain in both Python and C++.

Inheritance


In Python, Inheritance can be used to grant access to Parent class members and methods, so that Child classes can utilize them.

Let's create a Child class called Cashier and see the cookie ordering magic up close.

Step 1: We created a Child class called Cashier. We are calling this a Child class(Cashier) because it is deriving from the CookieFactory class - Cashier(CookieFactory).

Step 2: We gave our Child class a member called cashier. Since our Child class derives from the Parent class, we must add the Parent member(s) first and then our Child members.

Step 3: We utilized a function called super().__init__. This function allows us to access members and methods from our Parent class (CookieFactory). Within the super init function, we have to insert the member(s) from our Parent class.

Step 4: We gave our cashier member an instance.

Step 5: We created a member called Process(), which immitates a conversation between both the cashiers and the customers.

Step 6: We initialized our Child class constructor by creating an object(cashier) passing through a value for the Parent member(s) first, then the Child member(s).

Step 7: Lastly, we called the Process() method using our cashier objects.


In C++, just like in Python, Inheritance can be used to grant access to Parent class members, so that Child classes can utilize them. Let's create a Child class called Cashier and see the cookie ordering magic up close.

Step 1: We created a Child class called Cashier. We are calling this a Child class(Cashier) because it derives from the CookieFactory class - Cashier(CookieFactory).

Step 2: We gave our Child class a member called Cashier_. Since our Child class derives from the Parent class, we must add the Parent member(s) first and then our Child members.

Step 3: We attached our Parent constructor to our Child constructor. This allows us to access members and methods from our Parent class (CookieFactory).

Step 4: We gave our Cashier_ member an instance.

Step 5: We created a member called Process(), which immitates a conversation between both the cashiers and the customers.

Step 6: We initialized our Child class constructor by creating an object(cashier) passing through a value for the Parent member(s) first, then the Child member(s).

Step 7: Lastly, we called the Process() method using our cashier objects.

Abstraction

Abstraction in Python isn't supported directly. Using special methods or calling a Magic method allows for some form of Abstraction. C++ on the other hand, does support Abstraction directly.


In C++, Abstraction can be easily implemented by using the virtual keyword on the abstract class's method and can be called within another class without inheritance. Let's create a class that rates our cookies from Yum! to Best Seller (very biased, I know).

Step 1: We created a class called BestSelling that will serve as our abstract class and gave it a method called FanFave(). The (= 0) is known as a pure specifier, which is used to declare a virtual function. We use it because you must declare at least one member when creating an abstract class.

Step 2: We will attach it to our CookieFactory class. Note, we will not have to create a constructor that references our abstract class, because it's interface level. We are simply using our CookieFactory class as a backend for our abstract class.

Step 3: We recreated a FanFave() method and gave it a virtual keyword so that we can redefine it in our CookieFactory class.

Step 4: We used our objects to call the FanFave() method.

Encapsulation


In Python, we can make a member/attribute private by using a double underscore. We can use this for encapsulation.

Step1: We encapsulated our color member by adding two underscores between self. and the member.

Step 2: We created our setter and getter methods within our class. Notice the setter takes in a parameter(self.color). This is because the setter method will be used to set the color, while the getter method will return the color that was set. Also, notice we brought over encapsulated member to the setter and getter methods.

Step 3: We can now set our color within global scope. We set it to "brown" using our set_color method.

Step 4: We used our get_color() method to retrieve the Color.


In C++, we can use the private aM (access modifier), to encapsulate a member. We can access that member by creating setter and getter methods within our class. Let's set and get our cookie's Color.

Step1: We have encapsulated our Color member within our private aM.

Step 2: We created our setter and getter methods within our class. Notice the setter takes in a parameter(Color). This is because the setter method will be used to set the Color, while the getter method will return the Color that was set. Also, notice that our get_color method has a type string, because we are returning a string.

Step 3: We can now set our Color within the main scope. We set it to "brown" using our set_color method.

Step 4: We used our get_color() method to retrieve the Color.

Polymorphism


In Python, Polymorphism happens automatically. Let's say our customers wanted more than one cookie and we offered them a membership to our cookie factory. Let's set up our membership system:

Step 1: We created a Child class called CFMembership that derives from CookieFactory.

Step 2: Next, we created the same Flavor() method within our Child class and redefined it to allow the members to specify an amount.

Step 3: Lastly, we created our member(object) and pointed our customer to it. When we run this, customer_one Flavor() method will point to member_one Flavor() method.


In C++, implementing polymorphism takes a few steps. Let's say our customers wanted more than one cookie and we offered them a membership to our cookie factory. Let's set up our membership system:

Step 1: First, we needed to set the virtual keyword on our Parent class (CookieFactory) method called Flavor(). This allows us to redefine our Flavor() method within our Child class(CFMembership).

Step 2: Next, on our CFMembership class, we needed to set the Parent class to public (CFMembership: public CookieFactory{};). This allowed us to access the members using a pointer (*) and a reference (&).

Step 3: We redefined the Flavor() method within the Child class, which will allow our members(objects) to specify an amount.

Step 4: Lastly, we pointed our customers(objects) to our members(objects). Remember, we wanted to redefine our Flavor() method so that customers can become members and order more than one cookie at a time.

Get In Touch

Have an idea for a project in mind? Let's connect.