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
EasyLet'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 aProductclass 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
pricethat returns the private price - A setter
pricethat only accepts values greater than0(ignore invalid values) - A getter
quantitythat returns the private quantity - A setter
quantitythat only accepts values of0or greater (ignore negative values) - A computed getter
totalValuethat returns_price * _quantity - A computed getter
isInStockthat returnstrueif quantity is greater than0 - A read-only getter
skuthat generates a simple SKU by returning the first 3 characters of the name in uppercase followed by the quantity (e.g.,LAP25for "Laptop" with quantity 25) - A method
displayProduct()that shows the product details
- A public
main.dart: Import your product class and demonstrate how getters and setters control access:- Create a product named
'Laptop'with price999.99and quantity25 - 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]
- Create a product named
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: LAP0Cheat sheet
Getters and setters combined with private fields provide encapsulation and control over data access.
Private Field with Getter and Setter
class Temperature {
double _celsius = 0;
double get celsius => _celsius;
set celsius(double value) {
if (value < -273.15) {
_celsius = -273.15;
} else {
_celsius = value;
}
}
}Computed Getters
Getters can derive values from private data:
class Rectangle {
double _width;
double _height;
Rectangle(this._width, this._height);
double get area => _width * _height;
double get perimeter => 2 * (_width + _height);
double get width => _width;
set width(double value) {
if (value > 0) _width = value;
}
}Read-Only Access
Provide a getter without a setter for read-only properties:
class Order {
final DateTime _createdAt = DateTime.now();
DateTime get createdAt => _createdAt;
}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]"
}
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Fundamentals of OOP
External FilesLibraries & ImportsIntroduction to OOPClasses vs ObjectsThe this KeywordMethodsInstance VariablesConstructor BasicsRecap - Simple Calculator4Null Safety
Intro to Null SafetyNullable vs Non-NullableThe ? and ! OperatorsLate Keyword & Null SafetyNull-Aware OperatorsNull Safety in ClassesRecap - User Profile System7Abstract Classes & Interfaces
Abstract ClassesAbstract MethodsInterfaces in DartImplicit InterfacesImplementing vs ExtendingMultiple InterfacesRecap - Shape Calculator10Collections & Generics
List, Set, Map OverviewType-Safe CollectionsGeneric ClassesGeneric MethodsGeneric ConstraintsIterable & IteratorRecap - Generic Storage13Advanced OOP Concepts
Composition vs InheritanceExtension MethodsCallable ClassesSealed Classes (Dart 3)Records (Dart 3)Patterns & Matching (3.0)Enums with Methods16Project: Library Management
Project OverviewBook and User Classes2Constructors in Dart
Default ConstructorNamed ConstructorsInitializer ListsConstant ConstructorsFactory ConstructorsRedirecting ConstructorsRecap - Shape Builder5Encapsulation
Public vs Private MembersThe _ Prefix ConventionLibrary-Level PrivacyGetters & Setters DepthInformation HidingRecap - Student Records8Mixins
Introduction to MixinsCreating MixinsUsing Multiple Mixinson Keyword in MixinsMixin vs InheritanceMixin vs InterfaceRecap - Animal System11Special Methods
toString() OverridehashCode & == OverrideComparable Interfacecall() MethodnoSuchMethod OverrideRecap - Custom Collection14Design Patterns Part 1
Intro to Design PatternsSingleton PatternFactory PatternObserver PatternStrategy Pattern3Class Properties
Instance vs Static MembersFinal & Const FieldsLate VariablesStatic Methods & FieldsGetters and SettersRecap - Bank Account Manager6Inheritance
Basic InheritanceThe super KeywordMethod OverridingThe @override AnnotationThe final Class KeywordConstructors & InheritanceRecap - Employee Hierarchy9Polymorphism
Polymorphism BasicsPolymorphism via InterfacesRuntime Type CheckingThe is & as OperatorsCovariant KeywordRecap - Payment Processor