Menu
CoddyTech

Classes et méthodes abstraites

Fait partie de la section Programmation orientée objet du Journey Python de Coddy. Leçon 25 sur 64.

Les classes abstraites sont des classes qui ne peuvent pas être instanciées directement et qui contiennent des méthodes abstraites que les sous-classes doivent implémenter.

Imagine que c’est un formulaire : une classe abstraite ressemble à un formulaire obligatoire dont certains champs sont requis (les méthodes abstraites) et d’autres facultatifs (les méthodes concrètes). Tu ne peux pas soumettre le formulaire lui-même : tu dois d’abord remplir tous les champs requis. De même, tu ne peux pas créer d’instances d’une classe abstraite tant que toutes les méthodes abstraites n’ont pas été implémentées dans une sous-classe.

Importez le module abc pour créer des classes abstraites :

from abc import ABC, abstractmethod

Crée une classe abstraite avec des méthodes abstraites :

class Shape(ABC):
    @abstractmethod
    def area(self):
        pass
    
    @abstractmethod
    def perimeter(self):
        pass
    
    def describe(self):
        return "This is a shape"  # Méthode concrète (possède une implémentation)

Le décorateur @abstractmethod marque les méthodes qui doivent être implémentées par les sous-classes : ce sont les « champs obligatoires » de votre formulaire. Les méthodes ordinaires comme describe() peuvent avoir une implémentation et sont héritées telles quelles : ce sont les « champs préremplis ».

Pourquoi utiliser des classes abstraites ? Elles imposent un contrat. Si tu crées une classe Shape, tu affirmes que « chaque forme DOIT pouvoir calculer son aire et son périmètre ». Cela évite les bogues qui pourraient survenir si tu oubliais d’implémenter des méthodes essentielles.

Essaie de créer une instance de la classe abstraite :

# Cela provoquera une erreur :
# shape = Shape()  # TypeError: Can't instantiate abstract class

Cette erreur est intentionnelle : c’est comme essayer de soumettre un formulaire vide. Python dit : « Tu n’as pas encore rempli les champs obligatoires (les méthodes area et perimeter) ! »

Crée une sous-classe concrète qui implémente toutes les méthodes abstraites :

class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius
    
    def area(self):
        return 3.14 * self.radius ** 2
    
    def perimeter(self):
        return 2 * 3.14 * self.radius

Maintenant, nous avons « rempli tous les champs obligatoires » : nous avons implémenté à la fois area() et perimeter(). La classe Circle est désormais une classe concrète complète qui peut être instanciée.

Vous pouvez maintenant créer des instances de la classe concrète :

circle = Circle(5)
print(circle.area())
print(circle.perimeter())
print(circle.describe())  # Méthode concrète héritée

Crée une autre sous-classe concrète :

class Rectangle(Shape):
    def __init__(self, width, height):
        self.width = width
        self.height = height
    
    def area(self):
        return self.width  self.height
    
    def perimeter(self):
        return 2 * (self.width + self.height)

rectangle = Rectangle(4, 6)
print(rectangle.area())
print(rectangle.perimeter())

Sortie :

78.5
31.400000000000002
This is a shape
24
20

Les classes abstraites définissent un contrat que les sous-classes doivent respecter. Utilisez ABC et @abstractmethod pour créer des classes abstraites. Les sous-classes doivent implémenter toutes les méthodes abstraites, sinon elles seront elles aussi abstraites. Cela garantit la cohérence et évite les implémentations incomplètes.

challenge icon

Défi

Moyen

Dans ce défi, tu vas implémenter un système de traitement des paiements.

Tu dois terminer l’implémentation dans ces fichiers :

  • paymentmethod.py - Classe de base abstraite avec logique de validation
  • creditcard.py - Implémentation du paiement par carte de crédit
  • paypal.py - Implémentation du paiement par PayPal

Suis les commentaires TODO dans chaque fichier pour implémenter les fonctionnalités requises. Ces commentaires te guideront étape par étape dans la création de méthodes abstraites, l’implémentation de sous-classes concrètes et la mise en place de relations d’importation correctes entre les fichiers.

Le fichier driver.py contient des cas de test qui vérifieront que ton implémentation fonctionne correctement, en traitant différents scénarios de paiement et en affichant les détails appropriés pour chaque mode de paiement.

Essayez vous-même

from creditcard import CreditCard
from paypal import PayPal

# Testez les implémentations - NE MODIFIEZ PAS CE CODE DE TEST
cc = CreditCard("1234567890123456")
pp = PayPal("user@example.com")

# Traitez les paiements valides
if cc.validate(100):
    print(cc.process_payment(100))
    print(cc.payment_details())

if pp.validate(200):
    print(pp.process_payment(200))
    print(pp.payment_details())

# Essayez un montant invalide
if not pp.validate(0):
    print("Invalid payment amount")

# Cela provoquerait une erreur si cette ligne était décommentée :
# pm = PaymentMethod()  # Impossible d’instancier une classe abstraite
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Programmation orientée objet

Entraînez-vous par vous-même : Compilateur Python en ligne