Programmation objet
Motivation
sur ChatGPT, demander "give me a Python program that runs A* on a graph described as a png image (each white pixel is a vertex, and black pixels are obstacles)"
=> le résultat est un code monolithique. => Difficile d'avoir confiance, à comprendre, tester, vérifier => Difficile à améliorer => Difficile de réutiliser le code ailleurs
Struct
- LISP : en plus des listes, des objets avec des champs/attributs 1960s
Objet
Un objet est un ensemble de données (champs) + fonctions (méthodes). Une classe est une ensemble de champs et de définitions de méthodes.
- ALGOL W en 1966 : C. A. R. Hoare, champs/attributs et méthodes, mais pas de constructeurs
- Simula 67 par Ole-Johan Dahl and Kristen Nygaard in Norway :
- constructeur
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def norm():
return sqrt(self.x ** 2 + self.y ** 2)
p = Point(2, 3)
print(p.norm())
class Graph:
def __init__(self, n: int):
self.nbVertices = n
self.adjList: list[list[int]] = [[] for _ in range(n)]
def addEdge(self, u:int, v:int):
self.adjList[u].append(v)
def neighbors(self, v: int) -> list[int]:
return self.adjList[v]
Encapsulation
L' encapsulation a deux sens : le fait d'avoir les données et les méthodes. Mais aussi de cacher des champs aux utilisateurs.
- Simula 67 :
- naissances des champs privés et publics (privés = "hidden")
En Python, mettre __ devant le nom de champs et il est privé.
Apparté Python
[[]] * n VS [[] for _ in range(n)]
[2] * 3
Vision d'Alan Kay
Smalltalk 1970
- Encapsulation
- Message passing
- Liaison dynamique ~ Duck typing
class Cat:
def speak(self):
print("miaou")
class Dog:
def speak(self):
print("waouf")
L: list[Cat | Dog] = [Cat(), Dog(), Cat(), Cat()]
for animal in L:
animal.speak()
- isinstance(objet, class)
Héritage
Une classe A hérite de B si tout objet A est un B.
from abc import ABCMeta, abstractmethod
class Animal():
pass
class Cat(Animal):
def speak(self):
print("miaou")
class Dog(Animal):
def speak(self):
print("waouf")
L: list[Animal] = [Cat(), Dog(), Cat(), Cat()]
a = Animal() #fails
for animal in L:
animal.speak()
polymorphisme par héritage
- issubclass(class1, class2)
Classe abstraite
Une classe abstraite (Abstract Base Classes) est une classe où toutes les méthodes ne sont pas définies.
from abc import ABCMeta, abstractmethod
class Animal(metaclass=ABCMeta):
def hello(self):
print("hello")
@abstractmethod
def speak(self) -> None:
raise NotImplementedError
class Cat(Animal):
def speak(self):
print("miaou")
class Dog(Animal):
def speak(self):
print("waouf")
L: list[Animal] = [Cat(), Dog(), Cat(), Cat()]
a = Animal() #fails
for animal in L:
animal.hello()
animal.speak()
- Simula 67
- héritage
- méthodes virtuelles
Tout coder (sans type paramétrées)
Itérateur
-
Objet itérable : liste, etc.
-
Itérateur
-
Générateur
-
CLU (for "CLUsters") par Barbara Liskov en 1973 :
- types abstraits
- itérateurs
Types paramétrées (polymorphisme de type)
- types paramétrées (e.g List[T])
- types somme (e.g. List[T] | None)
- pas d'héritage (!)
Finir l'implémentation
Exemple de patron de conception
- Tableaunoir : patron de conception Command