Menu
Coddy logo textTech

Campos Final & Const

Parte da seção Programação Orientada a Objetos do Journey de Dart da Coddy — lição 18 de 110.

Ao declarar campos em uma classe, você pode usar final ou const para controlar se os valores podem mudar após a inicialização. Ambos criam valores imutáveis, mas funcionam de forma diferente.

Um campo final só pode ser definido uma vez, mas seu valor é determinado em tempo de execução. Você pode atribuí-lo na declaração ou por meio de um construtor:

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

Person p = Person('Alice');
// p.name = 'Bob';  // Erro: não é possível reatribuir um campo final

O name é definido quando o objeto é criado, e o createdAt captura a hora atual. Ambos os valores são bloqueados após a inicialização.

Um campo static const deve ter um valor conhecido em tempo de compilação. Ele pertence à própria classe e é compartilhado entre todas as instâncias:

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

A principal diferença: campos final podem conter valores computados em tempo de execução (como DateTime.now()), enquanto const exige constantes de tempo de compilação. Campos de instância não podem ser const diretamente - apenas static const é permitido no nível da classe.

challenge icon

Desafio

Fácil

Vamos construir um sistema de catálogo de produtos que demonstra a diferença entre campos final e static const. Você criará produtos com propriedades imutáveis e valores de configuração compartilhados.

Você organizará seu código em dois arquivos:

  • product.dart: Defina uma classe Product que representa um item em uma loja. Sua classe deve ter:
    • Um static const double taxRate definido como 0.08 (taxa de imposto de 8% compartilhada entre todos os produtos)
    • Um static const String currency definido como 'USD'
    • Um final String name para o nome do produto (definido via construtor)
    • Um final double basePrice para o preço base do produto (definido via construtor)
    • Um final String sku (unidade de manutenção de estoque) que combina um prefixo com o nome do produto, calculado em uma lista de inicialização como 'SKU-' seguido pelo nome em maiúsculas
    • Um construtor que recebe name e basePrice
    • Um getter priceWithTax que calcula o preço incluindo o imposto
    • Um método display() que imprime as informações do produto
  • main.dart: Importe sua classe de produto e crie dois produtos:
    • Um 'Laptop' com preço base 999.99
    • Um 'Mouse' com preço base 29.99
    Chame display() em cada produto na ordem listada acima.

O método display() deve imprimir exatamente neste formato:

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

Arredonde priceWithTax para 2 casas decimais usando toStringAsFixed(2) ao exibir.

Saída esperada:

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

Folha de consulta

Use final para campos que são definidos uma única vez em tempo de execução e não podem ser alterados posteriormente. Use static const para constantes de tempo de compilação compartilhadas entre todas as instâncias de uma classe.

Campos final são definidos em tempo de execução e podem ser inicializados na declaração ou no construtor:

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

Campos static const devem ter valores constantes em tempo de compilação e pertencem à própria classe:

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

Você pode calcular valores de campos final em uma lista de inicialização:

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

Principais diferenças:

  • final: Valores em tempo de execução, podem ser diferentes para cada instância
  • static const: Constantes em tempo de compilação, compartilhadas entre todas as instâncias
  • Campos de instância não podem ser const diretamente - apenas static const é permitido

Experimente você mesmo

import 'product.dart';

void main() {
  // TODO: Criar um Product chamado 'Laptop' com preço base 999.99
  
  // TODO: Criar um Product chamado 'Mouse' com preço base 29.99
  
  // TODO: Chamar display() em cada produto em ordem (Laptop primeiro, depois Mouse)
  
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos