Menu
Coddy logo textTech

Getters & Setters Depth

Part of the Object Oriented Programming section of Coddy's Dart journey. Lesson 33 of 110.

Getters and setters become powerful tools for encapsulation when combined with private fields. They let you expose a clean public interface while keeping full control over how data is accessed and modified.

A common pattern is pairing a private field with a public getter and a setter that includes validation:

class Temperature {
  double _celsius = 0;
  
  double get celsius => _celsius;
  
  set celsius(double value) {
    if (value < -273.15) {
      _celsius = -273.15;  // Absolute zero minimum
    } else {
      _celsius = value;
    }
  }
}

Setters can enforce business rules, ensuring your object never enters an invalid state.

You can also create computed getters that derive values from private data:

class Rectangle {
  double _width;
  double _height;
  
  Rectangle(this._width, this._height);
  
  double get area => _width * _height;      // Computed
  double get perimeter => 2 * (_width + _height);
  
  double get width => _width;
  set width(double value) {
    if (value > 0) _width = value;
  }
}

Sometimes you want read-only access. Simply provide a getter without a setter:

class Order {
  final DateTime _createdAt = DateTime.now();
  
  DateTime get createdAt => _createdAt;  // Read-only
}

This pattern gives external code visibility into the data while preventing any modifications - the private field combined with only a getter creates true read-only access.

challenge icon

Challenge

Easy

Let's build a product inventory system that showcases the power of getters and setters for controlling data access. You'll create a class that protects its internal data while providing computed properties and validation.

You'll organize your code into two files:

  • product.dart: Define a Product class that manages inventory with proper encapsulation. Your product should have:
    • A public String name
    • A private double _price
    • A private int _quantity
    • A constructor that takes all three values
    • A getter price that returns the private price
    • A setter price that only accepts values greater than 0 (ignore invalid values)
    • A getter quantity that returns the private quantity
    • A setter quantity that only accepts values of 0 or greater (ignore negative values)
    • A computed getter totalValue that returns _price * _quantity
    • A computed getter isInStock that returns true if quantity is greater than 0
    • A read-only getter sku that generates a simple SKU by returning the first 3 characters of the name in uppercase followed by the quantity (e.g., LAP25 for "Laptop" with quantity 25)
    • A method displayProduct() that shows the product details
  • main.dart: Import your product class and demonstrate how getters and setters control access:
    • Create a product named 'Laptop' with price 999.99 and quantity 25
    • Call displayProduct()
    • Print In stock: [isInStock]
    • Print SKU: [sku]
    • Attempt to set the price to -50.0 (should be ignored)
    • Set the price to 899.99 (valid change)
    • Attempt to set the quantity to -10 (should be ignored)
    • Set the quantity to 0 (valid change)
    • Call displayProduct()
    • Print In stock: [isInStock]
    • Print SKU: [sku]

The displayProduct() method should print in this format:

--- Product Info ---
Name: [name]
Price: $[price]
Quantity: [quantity]
Total Value: $[totalValue]

Expected output:

--- Product Info ---
Name: Laptop
Price: $999.99
Quantity: 25
Total Value: $24999.75
In stock: true
SKU: LAP25
--- Product Info ---
Name: Laptop
Price: $899.99
Quantity: 0
Total Value: $0.0
In stock: false
SKU: LAP0

Try it yourself

import 'product.dart';

void main() {
  // TODO: Create a product named 'Laptop' with price 999.99 and quantity 25

  // TODO: Call displayProduct()

  // TODO: Print "In stock: [isInStock]"

  // TODO: Print "SKU: [sku]"

  // TODO: Attempt to set price to -50.0 (should be ignored)

  // TODO: Set price to 899.99 (valid change)

  // TODO: Attempt to set quantity to -10 (should be ignored)

  // TODO: Set quantity to 0 (valid change)

  // TODO: Call displayProduct()

  // TODO: Print "In stock: [isInStock]"

  // TODO: Print "SKU: [sku]"
}
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

Practice on your own: Online Dart compiler