How to Use Object-Oriented Programming in Python
Tags: python, tutorial, 100daysofcode, languages
Published: 2020-09-25 22:24:32

Object-Oriented Programming (OOP) is a widely popular programming paradigm used across many different languages. This method of structuring a program uses **objects that have properties and behaviors**. Each programming language handles the principles of OOP a little differently, so it’s important to learn OOP for each language you are learning.  Today, we’ll discuss the basics of **OOP in Python** to propel your Python skills to the next level. 
 
Whether you're new to OOP or just curious about its use in Python, this is the perfect article to get started. You'll learn the benefits of OOP in Python and how to apply OOP concepts in your code. By the end of this article, you'll be able to create classes, initialize objects, and apply inheritance to your Python projects.
 
<br>

**Today we'll cover:**
* [What is Object-Oriented Programming?](#what)
* [OOP in Python](#oop-python)
* [How to define a class in Python](#class)
* [How to create an object in Python](#object)
* [How to create instance methods in Python](#method)
* [How to use inheritance in Python](#inheritance)
* [Putting it together: Calculator Problem](#calculator)
* [Refresher and moving forward](#conclusion)
 
<br>


<h3> <b> Master Python object-oriented programming the easy way </b>
 
Advance your Python skills with hands-on OOP lessons and practice problems.
 
<b>[Learn Object-Oriented Programming in Python](https://www.educative.io/courses/learn-object-oriented-programming-in-python)

<br>

<br>

<a name="what"></a>

## What is Object-Oriented Programming?

Object-Oriented Programming is a programming paradigm based on the creation of reusable "objects" that have their own properties and behavior that can be acted upon, manipulated, and bundled. 

These objects package related data and behaviors into representations of real-life objects. OOP is a widely used paradigm across various popular programming languages like Python, C++, and Java. 

Many developers use OOP because it makes your code **reusable** and logical, and it makes inheritance easier to implement. It follows the DRY principle, which makes programs much more efficient. 

In OOP, every object is defined with its own properties. For example, say our object is an Employee. These properties could be their name, age, and role. OOP makes it easy to model real-world things and the relationships between them. Many beginners prefer to use OOP languages because they organize data much like how the human brain organizes information. 

The four main principles of OOP are **inheritance**, **encapsulation**, **abstraction**, and **polymorphism**. To learn more about these, go read our article [What is Object Oriented Programming?](https://www.educative.io/blog/object-oriented-programming) for a refresher before continuing here.
 
Let’s refresh our memory on the building blocks of OOP before seeing how it works in Python.

<br>

### Properties

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/nj6ccd3bo87pln67fs37.PNG)

Properties are the data that describes an object. Each object has unique properties that can be accessed or manipulated by functions in the program. Think of these as  variables that describe the individual object. 

For example, a `sneaker1` object could have the properties `size` and  `isOnSale`. 

<br>

### Methods

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/bo0585k95f5ynvlebw6q.PNG)

Methods define the behavior of an object. Methods are like functions that are within the scope of an object. They're often used to alter the object's properties.  

For example, our `sneaker1` object would have the method `putOnSale` that switches the `isOnSale` property on or off. 

They can also be used to report on a specific object's properties. For example, the same `sneaker1` object could also have a `printInfo` method that displays its properties to the user.

<br>

### Classes

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/znxpq1sx86wtnkdtkixy.PNG)

Each object is created with a class. Think of this like the blueprint for a certain type of object. Classes list the properties essential to that type of object but do not assign them a value. Classes also define methods that are available to all objects of that type. 

For example, `sneaker1` was created from the class `Shoe` that defines our properties, `size` and `isOnSale`, and our methods, `putOnSale` and `printInfo`. All objects created from the `Shoe` class blueprint will have those same fields defined.

> Classes are like the umbrella category that each object falls under.

<br>
 
### Instances


![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/lr78dsz0xjwptnfb7olj.PNG)

An object is an instance of its parent class with a unique name and property values. You can have multiple instances of the same class type in a single program. Program calls are directed to individual instances whereas the class remains unchanged. 

For example, our `shoe` class could have two instances `sneaker1`, with a `size` of `8`, and `sneaker2`, with a `size` of `12`. Any changes made to the instance `sneaker1` will not affect `sneaker2`. 

<br>
 
<a name="oop-python"></a>

## OOP in Python

Python is a multi-paradigm programming language, meaning it supports OOP as well as other paradigms. You use classes to achieve OOP in Python. Python provides all the standard features of object-oriented programming.

Developers often choose to use OOP in their Python programs because it makes code more reusable and makes it easier to work with larger programs. OOP programs prevent you from repeating code because a class can be defined once and reused many times. OOP, therefore, makes it easy to achieve the "Don't Repeat Yourself" (DRY) principle.
 
Let’s see an example of how OOP improves Python. Say you organize your data with a list instead of a class. 

<br>
 
```py
sneaker1 = [8, true, "leather", 60]
```
 
<br>
 
Here, the list `sneaker1` contains the values for properties `size`, `isOnSale`, `material` and `cost`. This approach doesn't use OOP and can lead to several problems:
1. You must remember which index they used to store a certain type of data ie. `sneaker1`[0] =  size. This is not as intuitive as the object call of `sneaker1.size`
2. Not reusable. You have to create a new list for each item rather than just initializing a new object.
3. Difficult to create object-specific behavior. Lists cannot contain methods. Each list must call the same global function to achieve a given behavior rather than an object-specific method.

Instead, with OOP, we could write this as a `Shoe` class object to avoid these problems and make our code more useful down the line. 
 
<br>
 
```py
sneaker1 = Shoe(8, true, "leather", 60)
```
 
<br>
 
To avoid these problems, Python developers often use OOP over other available paradigms. Below we'll explore how you can implement OOP into your Python programs.

<br>
 
<div style="background-color:#F1F1FF;padding-left: 10px;padding-top:1px;padding-bottom:1px;">
 
## Keep learning Python OOP
Learn advanced Python OOP techniques from industry veterans. Educative's text-based courses are easily skimmed and give you the experience you need to land a job.
 
<b>[Learn Object-Oriented Programming in Python](https://www.educative.io/courses/learn-object-oriented-programming-in-python) </b>
</div>

<br>

<br>

<a name="class"></a>
## How to define a class in Python

To create a class in Python, we use the `class` keyword and a property like this:

```py
class MyClass:
  x = 4
```

Then we use `MyClass` to create an object like this:

```py
p1 = MyClass()
print(p1.x)
```

Let' take that  bit deeper. For the following examples, imagine that you're hired to make an online store for a shoe store. 
We'll learn how to use Python to define a `Shoe` class and the properties each shoe must have listed on the site.


First, we use the `class` keyword to begin our class and then set its name to `Shoe`. Each instance of `Shoe` will represent a different pair of shoes. We then list the properties each shoe will have, `size`, `isOnSale`, `material`, and `price`. Finally, we set each property to value `None`. We'll set each of these property values when we initialize a `Shoe` object.

<br>

```py
class Shoe:
    # define the properties and assign none value
    size = None
    isOnSale= None
    material = None
    price = None
```

<br>

> **Note: Spacing**
>
> Remember to include **four spaces** before all properties or methods within a class so that Python recognizes they're all within the defined class.

<br>
 
<a name="object"></a>
## How to create an object in Python

Now, we'll see how to initialize objects and set property values to represent each pair of shoes.


To create an object, we have to first set our initializer method. The initializer method is unique because it has a predefined name, `__init__`, and does not have a return value. The program automatically calls the initializer method when a new object from that class is created.
 
An initializer method should accept the special `self` parameter then all class properties as parameters. The `self` parameter allows the initializer method to select the newly created object instance. 
 
We then populate the initializer method with one instance variable initialization for each property. Each of these initializations sets a property of the created object to the value of the corresponding parameter. 

> For example, the first `self.size = size` sets the `size` property of the created object to equal the `size` parameter passed at object creation.
 
Once the initializer is set up, we can create an object with `[objectName] = Shoe()` and pass the necessary parameters. On line 10, we create a `Shoe` object called `sneaker3` with properties of `size = 11`, `isOnSale = false`, `material = "leather"`, and `price = 81`
 
We can use this code to create as many instances of `Shoe` that we need. 

<br>

```py
class Shoe:
    # defines the initializer method
    def __init__(self, size, isOnSale, material, price):
        self.size = size
        self.isOnSale = isOnSale
        self.material = material
        self.price = price

# creates an object of the Shoe class and sets 
# each property to an appropriate value
sneaker3 = Shoe(11, 'false', "leather", 81)
```

<br>
 
<a name="methods"></a>
## How to create instance methods in Python
Next, we'll add instance methods to our `Shoe` class so we can interact with object properties in our shoe store program. The main advantage of instance methods is that they're all available for any `Shoe` type object as soon as it is created. 

> To create instances, you call the class and pass the arguments that its `__init__` method accepts.

```py
class Shoe:
    # defines the initializer method
    def __init__(self, size, isOnSale, material, price):
        self.size = size
        self.isOnSale = isOnSale
        self.material = material
        self.price = price

    # Instance method
    def printInfo(self):
        return f" This pair of shoes are size {self.size}, are made of {self.material}, and costs ${self.price}"


   # Instance method
    def putOnSale(self):
        self.isOnSale = true

sneaker3 = Shoe(11, 'false', "leather", 81)

print (sneaker3.printInfo())
```

<br>

Our first instance method is `printInfo` that lists all properties except `isOnSale`. On line 10, we use the keyword `def` to begin declaring a new method, then name that method `printInfo` and finally list the special parameter `self`. 

In this case, `self` allows the method to access any parameter within the object this method is called on. We then write out our message on line 11 using `self.[property]` calls. 

> **Note:** This uses Python 3.6 f-string functionality. Any section of the message in curly brackets is not actually printed and instead prints the value of the stated property for the selected object.


Our second instance method, `putOnSale`, changes the value of the `isOnSale` property within the selected object to `true`. On line 15, we use the keyword `def`, our method name, and `self` parameter to define a method. 

Then we populate that method with a statement to change the `isOnSale` property to `true` on line 16. The first part of this statement selects the `isOnSale` property of the currently selected object. The second part of this statement sets the value of that selected property to `true`. 

Changing the value of this `Shoe` object's `isOnSale` property does not change the default value within the `Shoe` class. Python does not require a `return` value within every method.

<br>
 
<a name="inheritance"></a>
## How to use inheritance in Python
Finally, we'll add the subcategory `Sandal` of the `Shoe` class using inheritance. 
Inheritance allows a new class to take on the properties and behaviors from another class.
The class that is inherited from is called the **parent class**. Any class that inherits from a parent class is called a **child class**.
 
Child classes don't just inherit all properties and methods but can also expand or overwrite them.  

> **Expand** refers to the addition of properties or methods to the child class that are not present in the parent. **Overwrite** is the ability to redefine a method in a child class that has already been defined in the parent class.

The general syntax for single class inheritance is:

<br>

```py
class BaseClass:
  Base class body
class DerivedClass(BaseClass):
  Derived class body
```

<br>

We can also have multiple class inheritance:

<br>

```py
class BaseClass1:
  Base class1 body
class BaseClass:
  Base class2 body
class DerivedClass(BaseClass1,BaseClass2):
  Derived class body
```

<br>

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/mijs3twadcevg6feqckd.PNG)

<br>

To implement inheritance in Python, define a class as normal but add the name of its parent class in parentheses before the final colon (line 2).  

<br>

```py
#Sandal is the child class to parent class Shoe
class Sandal(Shoe):
    def __init__(self, size, isOnSale, material, price, waterproof):
    #inherit self, size, isOnSale, material, and price properties
       Shoe.__init__(self, size, isOnSale, material, price)
   #expands Sandal to contain additional property waterproof
       self.waterproof = waterproof
 
#overwrites printInfo to reference "pair of sandals" rather than shoes
    def printInfo(self):
        return f" This pair of sandals are size {self.size}, are made of {self.material}, and costs ${self.price}"

sandal1 = Sandal(11, False, "leather", 81, True)
 
print (sandal1.printInfo())
```

<br>



We then define a new initializer method that takes all properties from `Shoe` and adds an unique `waterproof` property. 


On line 3, we declare the initializer method for all properties we'll need from both parent and child classes. Then on line 5 we call the initializer method from the parent `Shoe` class to handle shared properties. We then expand beyond the inherited properties to add the `waterproof` property on line 7. 
 
You can use expanded classes to reduce rewritten code. If our class did not inherit from `Shoe`, we would need to recreate the entire initializer method to make just one small difference. 
 
Next, we overwrite the `printInfo` class defined in `Shoe` to be `Sandal` specific. Python will always use the most local definition of a method. 

Therefore, Python will use the newly defined `printInfo` method in `Sandal` over the inherited `printInfo` method from `Shoe` when the `printInfo` method is called.

<br>
 
<a name="calculator"></a>

## Putting it all together: Calculator Problem
Let’s put the skills you learned into practice with a challenge. Your goal is to write a Python class called `Calculator`. **There will be two steps to this challenge:** define the calculator's properties and add methods for each of the four operations.
 
**Task 1**

Write an initializer to initialize the values of `num1` and `num2`. The properties are `num1` and `num2`. 

**Task 2** 

Add four methods to the program:
* `add()`, a method which returns the sum of `num1` and `num2`.
* `subtract()`, a method which returns the subtraction of `num1` from num2.
* `multiply()`, a method which returns the product of `num1` and `num2`.
* `divide()`, a method which returns the division of `num2` by `num1`.

Your input will be the object's property integers and your output will be addition, subtraction, division, and multiplication results for those numbers. 



```py
# Sample input

obj = Calculator(10, 94);
obj.add()
obj.subtract()
obj.multiply()
obj.divide()

# Sample output

104
84
940
9.4
```
Try it out on your own and check the solution if you get stuck. 

Here's an empty program structure to get you started:

```py
class Calculator:
    def __init__(self):
        pass

    def add(self):
        pass

    def subtract(self):
        pass

    def multiply(self):
        pass

    def divide(self):
        pass
```

<br>

### Solution Breakdown

<br>

```py
class Calculator:
    def __init__(self, num1, num2):
        self.num1 = num1
        self.num2 = num2

    def add(self):
        return (self.num2 + self.num1)

    def subtract(self):
        return (self.num2 - self.num1)

    def multiply(self):
        return (self.num2 * self.num1)

    def divide(self):
        return (self.num2 / self.num1)


demo1 = Calculator(10, 94)
print("Addition:", demo1.add())
print("Subtraction:", demo1.subtract())
print("Mutliplication:", demo1.multiply())
print("Division:", demo1.divide())
```

<br>

Let’s dive into the solution. It’s okay if you didn’t get it the first time around! Practice is how we learn.
* We first implement the `Calculator` class with two properties: `num1` and `num2`.
* On **line 3-4**, we initialize both properties, `num1` and `num2`.
* On **line 7**, we implemented `add()`, a method that returns the sum, `num1` + `num1`, of both properties.
* On **line 10**, we implement `subtraction()`. This method returns the difference between `num1` and`num2`.
* On **line 13**, we implemented `multiplication()`, a method that returns the product of `num2` and `num1`.
* On **line 16**, we implement `division()`.  This method returns the quotient of `num2` by `num1`.

<br>
 
<a name="conclusion"></a>
## Refresher and moving forward
You've now completed your dive into the world of object-oriented Python programming. Today, we broke down the definition of object-oriented programming, why it's popular in Python, and walked you through the key parts of an object-oriented program in Python.

However, the concepts covered in this article are just the beginning of what OOP is capable of. The next topics to learn about in your OOP journey are:
* Data Encapsulation
* Polymorphism
* Aggregation
* Operator Overloading
* Information Hiding

Educative's **[Learn Object-Oriented Programming in Python](https://www.educative.io/courses/learn-object-oriented-programming-in-python)** is the ideal tool for learning OOP concepts quickly. With interactive examples and quizzes, this course makes sure you have the practice experience you need to apply OOP in your own programs. 

*Happy Learning!*

 
<br>
 
### Continue learning about Python and OOP
* [The Python FAQ: quick answers to common Python questions](https://www.educative.io/blog/python-faq-answer-common-python-questions)
* [Level up your Python skills with these 6 challenges](https://www.educative.io/blog/level-up-python-skills)
* [What is Object Oriented Programming? OOP Explained in Depth](https://www.educative.io/blog/object-oriented-programming)