Menu
Coddy logo textTech

Implémentations par défaut

Fait partie de la section Programmation Orientée Objet du Journey Rust de Coddy. Leçon 31 sur 61.

Jusqu’à présent, chaque méthode de trait que nous avons définie n’était qu’une signature : une exigence sans corps. Mais que se passe-t-il si la plupart des types implémentant un trait utilisent la même logique ? Rust vous permet de fournir une implémentation par défaut directement dans la définition du trait.

Au lieu de terminer la signature de la méthode par un point-virgule, vous ajoutez un corps :

trait Greet {
    fn greet(&self) -> String {
        String::from("Hello there!")
    }
}

Désormais, tout type qui implémente Greet obtient automatiquement cette méthode, sans écrire de code dans le bloc impl :

struct Guest;

impl Greet for Guest {}

let visitor = Guest;
println!("{}", visitor.greet());  // Bonjour !

Le impl Greet for Guest {} vide est valide, car le trait fournit déjà le comportement. La structure « adhère » simplement au trait et reçoit gratuitement la méthode par défaut.

Ce modèle est utile lorsque vous souhaitez définir un comportement partagé qui fonctionne dans la plupart des cas. Les types qui ont besoin de quelque chose de différent peuvent remplacer le comportement par défaut (ce que vous apprendrez ensuite), tandis que les types qui se satisfont du comportement standard n’ont pas besoin de se répéter.

challenge icon

Défi

Facile

Explorons la puissance des implémentations par défaut en construisant un système de notifications ! Tu vas créer un trait qui fournit un comportement standard prêt à l’emploi, afin que les types puissent l’adopter sans écrire de code répétitif.

Tu organiseras ton code dans trois fichiers :

  • notifiable.rs : définis un trait public Notifiable avec une méthode notify(&self) -> String qui possède une implémentation par défaut. Par défaut, elle doit retourner "You have a new notification!". Tout type qui implémente ce trait recevra automatiquement ce comportement sans avoir besoin de rien écrire dans son bloc impl.
  • alerts.rs : crée deux structures unitaires publiques simples qui implémentent ton trait :
    • EmailAlert : implémente Notifiable avec un bloc impl vide (utilise la valeur par défaut)
    • SystemAlert : implémente également Notifiable avec un bloc impl vide (utilise la valeur par défaut)
    Les deux structures recevront automatiquement le message de notification par défaut sans que tu aies à écrire le corps d’une quelconque méthode !
  • main.rs : rassemble tes modules et montre comment les deux types d’alertes partagent le même comportement par défaut. Crée des instances des deux structures et appelle leurs méthodes notify.

Dans ton fichier principal, crée un EmailAlert et un SystemAlert, puis affiche leurs notifications sur des lignes distinctes.

Ta sortie doit être :

You have a new notification!
You have a new notification!

Remarque que les deux types produisent une sortie identique : c’est là toute la beauté des implémentations par défaut ! Aucune des deux structures n’a eu besoin d’écrire du code pour la méthode notify, et pourtant toutes deux disposent d’un comportement de notification pleinement fonctionnel. Dans la prochaine leçon, tu apprendras à remplacer ces valeurs par défaut lorsqu’un type a besoin d’un comportement personnalisé.

Essayez vous-même

mod notifiable;
mod alerts;

use notifiable::Notifiable;
use alerts::{EmailAlert, SystemAlert};

fn main() {
    // TODO: Créer une instance de EmailAlert
    
    // TODO: Créer une instance de SystemAlert
    
    // TODO: Print the notification from EmailAlert
    
    // TODO: Print the notification from SystemAlert
}
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 Rust en ligne