Chapitre 2 : POO et classes.

🕐 Historique:

  • Origines (années 1960): Le concept de POO a été initié par le langage Simula, développé par Ole-Johan Dahl et Kristen Nygaard en Norvège. Simula introduit les notions de classes et d'héritage.
  • Popularisation (années 1970-1980): Smalltalk, développé par Alan Kay et d'autres au Xerox PARC, est le premier langage entièrement orienté objet. Il introduit des concepts tels que l'encapsulation, le polymorphisme et l'héritage.
  • Normalisation (années 1990): Avec l'émergence de langages tels que C++ et Java, la POO devient un standard dans le développement logiciel. Java popularise la POO avec sa plateforme permettant d'écrire un code une fois et de l'exécuter partout.
  • Évolution et diversification: La POO a été intégrée dans de nombreux autres langages de programmation, incluant Python, Ruby, et PHP. Les principes de POO ont été adaptés et étendus, contribuant à l'évolution continue des techniques de développement logiciel.

Aujourd'hui, la POO reste un pilier fondamental du développement logiciel, influençant la conception de systèmes logiciels complexes et la manière dont les développeurs pensent la résolution de problèmes informatiques.

Source : wikipedia

1. Paradigmes de programmation:

A copier dans le cahier.

Un paradigme de programmation est la façon dont un programme (ou un bout de programme) est construit.

2. Exemples:

Vous avez vu jusque là deux paradigmes de programmation : la programmation impérative et la programmation fonctionnelle.

Voici deux façons de compter le nombre de fois où la lettre "c" est présente dans 'coucou':

3. POO:

A copier dans le cahier.

Les lettres POO signifient Programmation Orientée Objet. C'est un troisième paradigme de programmation.

Cela désigne la possibilité dans un langage informatique à créer divers objets avec des propriétés et des méthodes associées.

Née en 1960, cette possibilité s'est démocratisée dans les années 1990.

4. Les classes d'objets dans Python:

Dans Python, pour créer des objets qui ne sont pas naturellement présent, on utilise l'instruction class.

Celui-ci doit impérativement contenir "le constructeur" def __init__(self): .

5. Méthodes, attributs:

Lorsque l'on crée une class, on peut y ajouter des méthodes et des attributs.

class Joueur:
    def __init__(self,pseudo):
        self.pseudo=pseudo        #ceci est un attribut
        self.points_de_vie=1000    #ceci est un attribut

    def change_pseudo(self,nouveau_pseudo):        #ceci est une méthode
        self.pseudo=nouveau_pseudo

    def get_pseudo(self):        #ceci est une méthode
        return self.pseudo

Par exemple, dans le code ci-dessus, on peut faire appel à l'attribut joueur1.pseudo ou encore à la méthode joueur1.get_pseudo()

6. Exercice :

Dans cet exercice, vous allez créer une classe CompteBancaire pour simuler la gestion d'un compte bancaire :

class CompteBancaire:
    def __init__(self, titulaire, solde_initial):
        # Initialiser les attributs ici

    # Définir la méthode pour déposer de l'argent

    # Définir la méthode pour retirer de l'argent

    # Définir la méthode pour afficher le solde actuel
  1. Complétez la classe CompteBancaire ci-dessus.
  2. Créez une instance de CompteBancaire avec le titulaire "Jean Dupont" et un solde initial de 1000 euros.
  3. Effectuez un dépôt de 250 euros, puis un retrait de 500 euros, et affichez le solde après ces opérations.
  4. Essayez de retirer un montant supérieur au solde disponible et gérez cette situation dans votre code.

7. Méthodes/attributs privés ou publiques:

A copier dans le cahier.

Lorsque l'on crée une classe, on peut avoir des méthodes ou des attributs privés. Ils ne sont alors pas accessibles depuis l'extérieur de la classe.

Dans Python, une méthode ou un attribut est par défaut publique mais peut être passé en privé en rajoutant __ devant.

8. Exemple:

class Joueur:
    def __init__(self,nom):
        self.pseudo=self.__crea_nom(nom)
        self.__point_de_vie=100
    
    def affiche_pv(self):
        return self.__point_de_vie

    def __crea_nom(self,mot):
        if mot=="aucun":
            return "Anonyme"
        else:
            return mot

Dans le code ci-dessus :

9. Exercice :

Dans cet exercice, vous allez créer une classe Livre pour gérer les informations d'une bibliothèque :

class Livre:
    def __init__(self, titre, auteur, annee_publication):
        # Initialiser les attributs ici

    # Définir la méthode affiche_info ici

    # Définir la méthode privée __verifie_annee ici
  1. Complétez la définition de la classe Livre.
  2. Créez deux instances de Livre avec les informations suivantes :
    • Livre 1 : Titre "Les Misérables", Auteur "Victor Hugo", Année de publication 1862.
    • Livre 2 : Titre "1984", Auteur "George Orwell", Année de publication 1949.
  3. Utilisez la méthode affiche_info pour afficher les informations de chaque livre.
  4. Essayez d'accéder directement à l'attribut privé __annee_publication de l'une des instances pour observer ce qui se passe.

10. Exercice : (sujet 32 - 2023)

On dispose d’une classe Carte permettant de créer des objets modélisant des cartes à jouer.

Compléter la classe Paquet_de_cartes suivante en respectant les spécifications données dans les chaînes de documentation.

Ajouter une assertion dans la méthode get_carte afin de vérifier que le paramètre pos est correct.

class Carte:
    def __init__(self, c, v):
        """ Initialise les attributs couleur (entre 1 et 4), et valeur (entre 1 et 13). """
        self.couleur = c
        self.valeur = v

    def get_valeur(self):
        """ Renvoie la valeur de la carte : As, 2, ..., 10, Valet, Dame, Roi """
        valeurs = ['As','2', '3', '4', '5', '6', '7', '8', '9', '10', 'Valet', 'Dame', 'Roi']
        return valeurs[self.valeur - 1]

    def get_couleur(self):
        """ Renvoie la couleur de la carte (parmi pique, coeur, carreau, trèfle). """
        couleurs = ['pique', 'coeur', 'carreau', 'trèfle']
        return couleurs[self.couleur - 1]

class Paquet_de_cartes:
    def __init__(self):
        """ Initialise l'attribut contenu avec une liste des 52 objets Carte possibles
            ranges par valeurs croissantes en commençant par pique, puis coeur,
            carreau et trèfle. """
        # A compléter

    def get_carte(self, pos):
        """ Renvoie la carte qui se trouve a  la position pos (entier compris entre 0 et 51). """
        # A compléter

Exemples :

>>> jeu = Paquet_de_cartes()
>>> carte1 = jeu.get_carte(20)
>>> print(carte1.get_valeur() + " de " + carte1.get_couleur())
8 de coeur
>>> carte2 = jeu.get_carte(0)
>>> print(carte2.get_valeur() + " de " + carte2.get_couleur())
As de pique
>>> carte3 = jeu.get_carte(52)
AssertionError : paramètre pos invalide

11. Exercice : (sujet 35 - 2023)

Dans cet exercice, on appelle carré d’ordre n un tableau de n lignes et n colonnes dont chaque case contient un entier naturel.

Exemples :

1 7
7 1

c2

Un carré d'ordre 2

3 4 5
4 4 4
5 4 3

c3

Un carré d'ordre 3

2 9 4
7 0 3
6 1 8

c3bis

Un autre carré d'ordre 3

Un carré est dit semimagique lorsque les sommes des éléments situés sur chaque ligne et chaque colonne sont égales.

La classe Carre en page suivante contient des méthodes qui permettent de manipuler des carrés :

Exemples :

>>> liste = (3, 4, 5, 4, 4, 4, 5, 4, 3)
>>> c3 = Carre(liste, 3)
>>> c3.affiche()
[3, 4, 5]
[4, 4, 4]
[5, 4, 3]

Compléter la méthode est_semimagique qui renvoie True si le carré est semimagique, False sinon. Puis tester la fonction est_semimagique sur les carrés c2, c3 et c3bis.

c2 = [[1, 7], [7, 1]]
c3 = [[3, 4, 5], [4, 4, 4], [5, 4, 3]]
c3bis = [[2, 9, 4], [7, 0, 3], [6, 1, 8]]


class Carre:
    def __init__(self, liste, n):
        self.ordre = n
        self.tableau = [[liste[i + j * n] for i in range(n)] for j in range(n)]

    def affiche(self):
        '''Affiche un carré'''
        for i in range(self.ordre):
            print(self.tableau[i])

    def somme_ligne(self, i):
        '''Calcule la somme des valeurs de la ligne i'''
        somme = 0
        for j in range(self.ordre):
            somme = somme + self.tableau[i][j]
        return somme

    def somme_col(self, j):
        '''Calcule la somme des valeurs de la colonne j'''
        somme = 0
        for i in range(self.ordre):
            somme = somme + self.tableau[i][j]
        return somme

    def est_semimagique(self):
        s = self.somme_ligne(0)

        #test de la somme de chaque ligne
        for i in range(...):
            if ... != s:
                return ...

        #test de la somme de chaque colonne
        for j in range(...):
            if ... != s:
                return ...

        return ...

12. Projet:

Projet : créer un programme Python faisant intervenir les classes.

Consignes :