Object-oriented programming (OOP) is a computer programming model that organizes software design around data, or objects, rather than functions and logic. An object can be defined as a data field that has unique attributes and behavior.
Main Concepts
- Encapsulation
- Abstraction
- Inheritance
- Polymorphism
Other Concepts
- Attributes: there is instance and class categories
- Methods: functions defined inside the class
- Class Methods: This should do something that has a relationship with the class, but usually, those are used to manipulate different structures of data to instantiate objects, like we have done with CSV.
- Static Methods: Don’t have the self parameter reference. This should do something that has a relationship with the class, but not something that must be unique per instance.
- Objects: are the instances of a class
- Private Attributes: attributes that can’t be accessed directly _( _name )
- Private Methods: methods that can’t be accessed directly _( _method() )
- Abstract Classes: a kind of class template, blocks the creation of an instance of the class
- Abstract Methods: a method that has a declaration but does not have an implementation
- Getters: used to retrieve some attribute
- Setters: used to set new value to some attribute
- Magic Methods: a.k.a dunder methods
- Magic Attributes
Basic Example
class Item:
pass
new_item = Item()
new_item.name = "Computer" # creating an attribute for the instance
Complete Example
import csv
class Item:
# class attributes
pay_rate = 0.6
all = []
# constructor method
def __init__(self, name: str, price: float, qty: int = 0):
# data validation
assert price >= 0, "Price have a invalid value !"
assert qty >= 0, "Qty have a invalid value !"
# assignments - instance attributes
self.name = name
self.price = price
self.qty = qty
# actions to execute
Item.all.append(self)
# method example 1
def calculate_total_price(self):
return self.price * self.qty
# method example 2
def apply_discount(self):
self.price = self.price * self.pay_rate # Item.pay_rate
# class method
@classmethod
def instantiate_from_csv(cls):
with open("data.csv", "r") as f:
reader = csv.DictReader(f)
items = list(reader)
for item in items:
Item(
name=item.get("name"),
price=float(item.get("price")),
qty=int(item.get("qty")),
)
# static method
@staticmethod
def check_integer(num):
if isinstance(num, float):
return num.is_integer()
elif isinstance(num, int):
return True
else:
return False
# defining the object representation
def __repr__(self):
return f"{self.__class__.__name__}('{self.name}', {self.price}, {self.qty})"
new_item_a = Item("Car", 1500, 2)
new_item_b = Item("PC", 2000, 1)
new_item_c = Item("GPU", 5000, 3)
print(Item.all)
Item.instantiate_from_csv()
Item.check_integer(7)
Inheritance Example
class Computer(Item):
def __init__(self, name: str, price: float, qty: int = 0, brokens=0):
super().__init__(name, price, qty)
assert brokens >= 0, "Brokens items have a invalid value !"
self.brokens = brokens
Using Getters and Setters Example
class Item:
# class attributes
pay_rate = 0.6
all = []
# constructor method
def __init__(self, name: str, price: float, qty: int = 0):
# data validation
assert price >= 0, "Price have a invalid value !"
assert qty >= 0, "Qty have a invalid value !"
# assignments - instance attributes
self.__name = name
self.price = price
self.qty = qty
# actions to execute
Item.all.append(self)
# method example 1
def calculate_total_price(self):
return self.price * self.qty
# method example 2
def apply_discount(self):
self.price = self.price * self.pay_rate # Item.pay_rate
# class method
@classmethod
def instantiate_from_csv(cls):
with open("data.csv", "r") as f:
reader = csv.DictReader(f)
items = list(reader)
for item in items:
Item(
name=item.get("name"),
price=float(item.get("price")),
qty=int(item.get("qty")),
)
# static method
@staticmethod
def check_integer(num):
if isinstance(num, float):
return num.is_integer()
elif isinstance(num, int):
return True
else:
return False
# defining the object representation
def __repr__(self):
return f"{self.__class__.__name__}('{self.name}', {self.price}, {self.qty})"
# property decorator - read-only attribute - Getters
@property
def name(self):
return self.__name
# property decorator - allow to set a new value - Setters
@name.setter
def name(self, value):
self.__name = value
Abstract Class and Methods Examples
from abc import ABC, abstractmethod
class Vehicle(ABC):
@abstractmethod
def go(self):
pass
class Car(Vehicle):
def go(self):
print("Riding a car !")