Menu
Coddy logo textTech

Champs Final & Const

Fait partie de la section Programmation Orientée Objet du Journey Dart de Coddy — leçon 18 sur 110.

Lors de la déclaration de champs dans une classe, vous pouvez utiliser final ou const pour contrôler si les valeurs peuvent changer après l'initialisation. Les deux créent des valeurs immuables, mais ils fonctionnent différemment.

Un champ final ne peut être défini qu'une seule fois, mais sa valeur est déterminée à l'exécution. Vous pouvez l'assigner lors de la déclaration ou via un constructeur :

class Person {
  final String name;
  final DateTime createdAt = DateTime.now();
  
  Person(this.name);
}

Person p = Person('Alice');
// p.name = 'Bob';  // Erreur : impossible de réassigner un champ final

Le name est défini lors de la création de l'objet, et createdAt capture l'heure actuelle. Les deux valeurs sont verrouillées après l'initialisation.

Un champ static const doit avoir une valeur connue au moment de la compilation. Il appartient à la classe elle-même et est partagé entre toutes les instances :

class Circle {
  static const double pi = 3.14159;
  final double radius;
  
  Circle(this.radius);
  
  double get area => Circle.pi * radius * radius;
}

La différence clé : les champs final peuvent contenir des valeurs calculées au moment de l'exécution (comme DateTime.now()), alors que const nécessite des constantes au moment de la compilation. Les champs d'instance ne peuvent pas être const directement - seul static const est autorisé au niveau de la classe.

challenge icon

Défi

Facile

Construisons un système de catalogue de produits qui démontre la différence entre les champs final et static const. Vous allez créer des produits avec des propriétés immuables et des valeurs de configuration partagées.

Vous organiserez votre code en deux fichiers :

  • product.dart : Définissez une classe Product qui représente un article dans un magasin. Votre classe doit avoir :
    • Un static const double taxRate défini à 0.08 (taux de taxe de 8 % partagé par tous les produits)
    • Un static const String currency défini à 'USD'
    • Un final String name pour le nom du produit (défini via le constructeur)
    • Un final double basePrice pour le prix de base du produit (défini via le constructeur)
    • Un final String sku (unité de gestion des stocks) qui combine un préfixe avec le nom du produit, calculé dans une liste d'initialisation comme 'SKU-' suivi du nom en majuscules
    • Un constructeur qui prend name et basePrice
    • Un getter priceWithTax qui calcule le prix incluant la taxe
    • Une méthode display() qui affiche les informations du produit
  • main.dart : Importez votre classe de produit et créez deux produits :
    • Un 'Laptop' avec un prix de base de 999.99
    • Un 'Mouse' avec un prix de base de 29.99
    Appelez display() sur chaque produit dans l'ordre listé ci-dessus.

La méthode display() doit afficher les informations exactement dans ce format :

[sku] - [name]: [basePrice] [currency] (with tax: [priceWithTax] [currency])

Arrondissez priceWithTax à 2 décimales en utilisant toStringAsFixed(2) lors de l'affichage.

Sortie attendue :

SKU-LAPTOP - Laptop: 999.99 USD (with tax: 1079.99 USD)
SKU-MOUSE - Mouse: 29.99 USD (with tax: 32.39 USD)

Aide-mémoire

Utilisez final pour les champs qui sont définis une seule fois à l'exécution et qui ne peuvent plus être modifiés par la suite. Utilisez static const pour les constantes de compilation partagées par toutes les instances d'une classe.

Les champs final sont définis à l'exécution et peuvent être initialisés lors de la déclaration ou dans le constructeur :

class Person {
  final String name;
  final DateTime createdAt = DateTime.now();
  
  Person(this.name);
}

Les champs static const doivent avoir des valeurs constantes à la compilation et appartiennent à la classe elle-même :

class Circle {
  static const double pi = 3.14159;
  final double radius;
  
  Circle(this.radius);
  
  double get area => Circle.pi * radius * radius;
}

Vous pouvez calculer les valeurs des champs final dans une liste d'initialisation :

class Product {
  final String name;
  final String sku;
  
  Product(this.name) : sku = 'SKU-${name.toUpperCase()}';
}

Différences clés :

  • final : Valeurs à l'exécution, peuvent être différentes pour chaque instance
  • static const : Constantes à la compilation, partagées par toutes les instances
  • Les champs d'instance ne peuvent pas être const directement - seul static const est autorisé

Essayez vous-même

import 'product.dart';

void main() {
  // TODO: Créer un Product appelé 'Laptop' avec un prix de base de 999.99
  
  // TODO: Créer un Product appelé 'Mouse' avec un prix de base de 29.99
  
  // TODO: Appeler display() sur chaque produit dans l'ordre (Laptop d'abord, puis Mouse)
  
}
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