Menu
Coddy logo textTech

Final & Const Fields

Part of the Object Oriented Programming section of Coddy's Dart journey — lesson 18 of 110.

When declaring fields in a class, you can use final or const to control whether values can change after initialization. Both create immutable values, but they work differently.

A final field can only be set once, but its value is determined at runtime. You can assign it in the declaration or through a constructor:

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

Person p = Person('Alice');
// p.name = 'Bob';  // Error: can't reassign final field

The name is set when the object is created, and createdAt captures the current time. Both values are locked after initialization.

A static const field must have a value known at compile time. It belongs to the class itself and is shared across all instances:

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

The key difference: final fields can hold values computed at runtime (like DateTime.now()), while const requires compile-time constants. Instance fields cannot be const directly - only static const is allowed at the class level.

challenge icon

Challenge

Easy

Let's build a product catalog system that demonstrates the difference between final and static const fields. You'll create products with immutable properties and shared configuration values.

You'll organize your code into two files:

  • product.dart: Define a Product class that represents an item in a store. Your class should have:
    • A static const double taxRate set to 0.08 (8% tax rate shared across all products)
    • A static const String currency set to 'USD'
    • A final String name for the product name (set via constructor)
    • A final double basePrice for the product's base price (set via constructor)
    • A final String sku (stock keeping unit) that combines a prefix with the product name, calculated in an initializer list as 'SKU-' followed by the uppercase name
    • A constructor that takes name and basePrice
    • A getter priceWithTax that calculates the price including tax
    • A display() method that prints the product information
  • main.dart: Import your product class and create two products:
    • A 'Laptop' with base price 999.99
    • A 'Mouse' with base price 29.99
    Call display() on each product in the order listed above.

The display() method should print in this exact format:

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

Round priceWithTax to 2 decimal places using toStringAsFixed(2) when displaying.

Expected output:

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

Cheat sheet

Use final for fields that are set once at runtime and cannot be changed afterward. Use static const for compile-time constants shared across all instances of a class.

final fields are set at runtime and can be initialized in the declaration or constructor:

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

static const fields must have compile-time constant values and belong to the class itself:

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

You can compute final field values in an initializer list:

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

Key differences:

  • final: Runtime values, can be different for each instance
  • static const: Compile-time constants, shared across all instances
  • Instance fields cannot be const directly - only static const is allowed

Try it yourself

import 'product.dart';

void main() {
  // TODO: Create a Product called 'Laptop' with base price 999.99
  
  // TODO: Create a Product called 'Mouse' with base price 29.99
  
  // TODO: Call display() on each product in order (Laptop first, then Mouse)
  
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming