Day 5.1 - CH10 - Object Oriented Programming
Day 5.1 - CH10 - Object Oriented Programming
ALGORITHMS WITH
PYTHON
4
Concept : A dog
Name
Attributes
Age
Dog
Bark
Actions Sleep
Run
5
Four pillars of OOP
6
Benefits of OOP
7
OOP in python
8
Objects creations
# class definition
class Dog:
pass
9
Class constructor
10
Class constructor - example
# class definition
class User:
# constructor definition
def __init__(self, name: str):
# self represents the current instance
self.name = name
class User:
ROLE = "viewer" # class attribute
bob = User("Bob")
alice = User("Alice")
print(bob.name, bob.ROLE)
>>> Bob viewer
print(alice.name, alice.ROLE)
>>> Alice viewer
13
Instance methods
14
Methods - example
class User:
def __init__(self, name: str):
self.name = name
def say_hi(self):
print(f"Hi, my name is {self.name}.")
bob = User("Bob")
bob.say_hi()
- Newly formed class is a child and takes all the attributes and methods of its parent.
17
Inheritance - schema
18
Inheritance – example
class Animal:
def eat(self):
print("I am eating.")
class Dog(Animal):
def bark(self):
print("I am barking.")
my_dog = Dog()
19
Overriding methods
class Parent:
def example_method(self):
print("Method of the Parent class.")
class Child(Parent):
# method has the same name as the one from the parent
def example_method(self):
print("Method of the Child class.")
obj = Child()
obj.example_method()
20
Calling parents : the super() built-in
class Child(Parent):
def example_method(self):
# super() is used to call the method from the parent
super().example_method()
print("Method of the Child class.")
obj = Child()
obj.example_method()
def make_sound(self):
print(self.sound)
class Dog(Animal):
def __init__(self, name: str, sound: str = "Woof"):
super().__init__(sound) # call the parent constructor
self.name = name
my_dog = Dog("Bob")
my_dog.make_sound()
23
Checking if an instance belongs to a class
24
Using isinstance() - example
class Base: pass
class A(Base): pass
class B(Base): pass
class Other: pass
25
Encapsulation
26
Restrict access from outside
the class
27
Encapsulation scope
protected Accessible only from the class and its childs _name
Note that in Python this is mainly used as an indication and can be bypassed...
28
Encapsulation example
class Item:
def __init__(self, id: int, name: str, quantity: int):
self.__id = id # private
self._name = name # protected
self.quantity = quantity # public
class Phone(Item):
def __init__(self, id: int, name: str, quantity: int):
super().__init__(id, name, quantity)
Public • Nothing
30
Working with private attributes
Accessors
31
Basic getters / setters
class Item:
def __init__(self, quantity: int):
self.__quantity = quantity
item = Item(3)
item.get_quantity() # returns 3
item.set_quantity(1) # quantity is now 1
32
The @property decorator
33
The @property decorator
class Item:
def __init__(self, quantity: int):
self.__quantity = quantity
@property
def quantity(self) -> int:
return self.__quantity
@quantity.setter
def quantity(self, quantity: int) -> int:
if quantity < 0:
raise ValueError("quantity can't be less than 0")
self.__quantity = quantity
item = Item(3)
item.quantity # returns 3
item.quantity = 1 # quantity is now 1
34
Abstraction
35
Abstraction concepts
36
The Abstract Base Class (abc) module
class Animal(ABC):
@abstractmethod
def make_noise(self):
pass
class Dog(Animal):
def make_noise(self):
print("Woof woof")
39
Polymorphism explained
A method or function that can Behaviors can depend on the class Related concept to inheritance.
have different behaviors. or context.
40
Polymorphism behaviors - examples
41
Polymorphism with OOP example
from abc import ABC, abstractmethod
class Animal(ABC):
@abstractmethod
def make_noise(self):
pass
class Dog(Animal):
def make_noise(self):
print("Woof woof")
class Cat(Animal):
def make_noise(self):
print("Meow Meow")
42
Operator overloading
43
Operator overload
44
Operator override - example
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
a = Vector(4, 2)
b = Vector(1, 1)
c = a + b # Vector(5, 3)
45
Operator overload - maths
Operator method
+ __add__(self, other)
- __sub__(self, other)
* __mul__(self, other)
/ __truediv__(self, other)
// __floordiv__(self, other)
% __mod__(self, other)
** __pow__(self, other)
46
Operator overload - assignment
Operator method
+= __iadd__(self, other)
-= __isub__(self, other)
*= __imul__(self, other)
/= __itruediv__(self, other)
//= __ifloordiv__(self, other)
%= __imod__(self, other)
**= __ipow__(self, other)
47
Operator overload - comparison
Operator method
< __lt__(self, other)
> __gt__(self, other)
<= __le__(self, other)
>= __ge__(self, other)
== __eq__(self, other)
!= __ne__(self, other)
48
List all magic methods
- Can list all methods implemented with the dir() built-in function.
dir( object )
49
Representation override
50
Representation override
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
v = Vector(4, 2)
print(v) # Vector{4, 2}
51
Dataclasses
52
Dataclasses
53
Dataclasses benefits
- Conciseness : automatically generates special methods
- Readability : makes the code more readable
- Default values : you can provide default values in the class declaration
- Immutability : dataclasses are perfects to use as immutable objects
- Equality Comparison : automatically provide __eq__ support
- Hash support : automatically provide __hash__ so they can be used as keys in dict
54
Dataclasses - example
55
Dataclasses – frozen example
@dataclass
class ForceUser:
name: str
age: int
job: str = "Jedi"
58
Let’s practice !
59