Zum Hauptinhalt springen
Echtzeit-Radar & Feeds
Alle RSS Feeds ➔
👥 Community & Social
YouTube Security VideosIBM Technology: Why Did The AI Race Just Change? 🏁(25.09.2026 um 18:00 Uhr)
••
YouTube Security VideosIBM Technology: Prompt to Production: The Future of AI Code Workflows(28.09.2026 um 13:00 Uhr)
•
YouTube Security VideosVisual Studio Code: 5 Shortcuts You Need in VS Code ⚡(25.09.2026 um 16:00 Uhr)
•
YouTube Security VideosMeteomatics doubles weather forecast output with AMD(25.09.2026 um 16:00 Uhr)
•
YouTube Security VideosMindwalk cuts drug discovery compute time with AMD(25.09.2026 um 16:00 Uhr)
•
YouTube Security VideosVDURA advances AI data infrastructure performance with AMD(28.09.2026 um 16:00 Uhr)
•
YouTube Security VideosThe Hated One: IT'S HAPPENING...(25.09.2026 um 17:15 Uhr)
•
YouTube Security VideosTechquickie: Every Intel Chip Name in 7 minutes(25.09.2026 um 21:34 Uhr)
•
Podcasts & Audio BriefingsTechLinked: Anyway,(26.09.2026 um 02:40 Uhr)
•
YouTube Security VideosIBM Technology: Why Did The AI Race Just Change? 🏁(25.09.2026 um 18:00 Uhr)
••
YouTube Security VideosIBM Technology: Prompt to Production: The Future of AI Code Workflows(28.09.2026 um 13:00 Uhr)
•
YouTube Security VideosVisual Studio Code: 5 Shortcuts You Need in VS Code ⚡(25.09.2026 um 16:00 Uhr)
•
YouTube Security VideosMeteomatics doubles weather forecast output with AMD(25.09.2026 um 16:00 Uhr)
•
YouTube Security VideosMindwalk cuts drug discovery compute time with AMD(25.09.2026 um 16:00 Uhr)
•
YouTube Security VideosVDURA advances AI data infrastructure performance with AMD(28.09.2026 um 16:00 Uhr)
•
YouTube Security VideosThe Hated One: IT'S HAPPENING...(25.09.2026 um 17:15 Uhr)
•
YouTube Security VideosTechquickie: Every Intel Chip Name in 7 minutes(25.09.2026 um 21:34 Uhr)
•
Podcasts & Audio BriefingsTechLinked: Anyway,(26.09.2026 um 02:40 Uhr)
•
Intelligence View
⚡ tsecurity.de Intelligence

Dart Object Oriented For Beginner : Expense Manager Case Study Part 3

Lesson 3: Different Ways to Create Expenses Duration: 25 minutes App Feature: 🔧 Making Expense Creation Easier What You'll Build: Add multiple ways to create expenses with constructors Prerequisites: Complete Lesson 1 & 2 W…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!




Lesson 3: Different Ways to Create Expenses



Duration: 25 minutes


App Feature: 🔧 Making Expense Creation Easier


What You'll Build: Add multiple ways to create expenses with constructors


Prerequisites: Complete Lesson 1 & 2







What We'll Learn Today



By the end of this lesson, you'll be able to:




  • ✅ Create named constructors for easier object creation

  • ✅ Use optional parameters

  • ✅ Set default values

  • ✅ Build multiple constructor variations

  • ✅ Make your code more flexible and user-friendly







Review: What We Know About Constructors



In Lesson 2, we learned the basic constructor:




class Expense {
String description;
double amount;
String category;
DateTime date;

Expense(this.description, this.amount, this.category, this.date);
}

void main() {
var coffee = Expense('Coffee', 4.50, 'Food', DateTime.now());
}






The Problem: Every time we create an expense, we need to provide ALL four values. But what if:




  • Most expenses are from today? (we always type DateTime.now())

  • We want quick shortcuts for common scenarios?

  • Some values have sensible defaults?



The Solution: Named constructors and optional parameters!









Part 1: Named Constructors



A named constructor is an alternative way to create objects. You can have multiple constructors in one class, each with a different name.






Syntax:






ClassName.constructorName(parameters)









Example: Quick Expense Constructor






class Expense {
String description;
double amount;
String category;
DateTime date;

// Regular constructor
Expense(this.description, this.amount, this.category, this.date);

// Named constructor - assumes today's date
Expense.quick(this.description, this.amount, this.category)
: date = DateTime.now();
}

void main() {
// Using regular constructor
var laptop = Expense('Laptop', 899.99, 'Electronics', DateTime(2025, 10, 5));

// Using named constructor - much shorter!
var coffee = Expense.quick('Coffee', 4.50, 'Food');
var lunch = Expense.quick('Lunch', 12.75, 'Food');

print('${coffee.description}: \$${coffee.amount} on ${coffee.date}');
}









Understanding the Syntax:






Expense.quick(this.description, this.amount, this.category) 
: date = DateTime.now();








  • Expense.quick = class name + dot + constructor name

  • Parameters in () work like normal constructor


  • : date = DateTime.now() is the initializer list

  • Sets date property before the object is fully created









Part 2: Building a Better Expense Class



Let's add several named constructors for common scenarios:




class Expense {
String description;
double amount;
String category;
DateTime date;

// 1. Regular constructor - full control
Expense(this.description, this.amount, this.category, this.date);

// 2. Quick constructor - assumes today
Expense.quick(this.description, this.amount, this.category)
: date = DateTime.now();

// 3. Monthly bill constructor - assumes "Bills" category
Expense.monthly(this.description, this.amount)
: category = 'Bills',
date = DateTime.now();

// 4. Yesterday constructor - for when you forget to log
Expense.yesterday(this.description, this.amount, this.category)
: date = DateTime.now().subtract(Duration(days: 1));

void printDetails() {
print('$description: \$${amount.toStringAsFixed(2)} [$category] on ${date.toString().split(' ')[0]}');
}
}

void main() {
print('MY EXPENSES:\n');

// Using different constructors
var rent = Expense.monthly('Rent', 1200.0);
var coffee = Expense.quick('Coffee', 4.50, 'Food');
var dinner = Expense.yesterday('Dinner', 35.00, 'Food');
var vacation = Expense('Flight', 450.0, 'Travel', DateTime(2025, 12, 20));

rent.printDetails();
coffee.printDetails();
dinner.printDetails();
vacation.printDetails();
}






Output:




MY EXPENSES:

Rent: $1200.00 [Bills] on 2025-10-09
Coffee: $4.50 [Food] on 2025-10-09
Dinner: $35.00 [Food] on 2025-10-08
Flight: $450.00 [Travel] on 2025-12-20












Part 3: Multiple Initializations in Initializer List



You can set multiple properties in the initializer list:




class Expense {
String description;
double amount;
String category;
DateTime date;

Expense(this.description, this.amount, this.category, this.date);

// Initialize BOTH category and date
Expense.subscription(this.description, this.amount)
: category = 'Entertainment',
date = DateTime.now();

// Initialize with calculations
Expense.weekly(this.description, double weeklyAmount)
: amount = weeklyAmount * 52, // Convert to yearly
category = 'Recurring',
date = DateTime.now();
}

void main() {
var netflix = Expense.subscription('Netflix', 15.99);
var coffee = Expense.weekly('Coffee habit', 25.00); // $25/week

netflix.printDetails();
print('Coffee yearly: \$${coffee.amount.toStringAsFixed(2)}');
}









Key Points:




  • Separate multiple initializations with commas

  • Can include calculations or method calls

  • Runs BEFORE the constructor body (if you have one)









Part 4: Optional Parameters



Sometimes you want parameters that are... optional! Dart has two ways to do this:






A. Optional Positional Parameters (with [])






class Expense {
String description;
double amount;
String category;
DateTime date;
String? notes; // Nullable - can be null

// Optional positional parameters in square brackets
Expense(this.description, this.amount, this.category, [DateTime? date, this.notes])
: date = date ?? DateTime.now(); // Use provided date OR current date
}

void main() {
// With date and notes
var expense1 = Expense('Laptop', 899.99, 'Electronics', DateTime(2025, 10, 5), 'Work laptop');

// Without date (uses today)
var expense2 = Expense('Coffee', 4.50, 'Food');

// With date but no notes
var expense3 = Expense('Dinner', 45.00, 'Food', DateTime(2025, 10, 8));
}






Understanding ?? operator:





  • date ?? DateTime.now() means: "use date if provided, otherwise use DateTime.now()"

  • This is called the "null-aware" operator






B. Named Optional Parameters (with {})



Named parameters are more readable and can be provided in any order:




class Expense {
String description;
double amount;
String category;
DateTime date;
String? notes;
bool isPaid;

// Named optional parameters in curly braces
Expense({
required this.description,
required this.amount,
required this.category,
DateTime? date,
this.notes,
this.isPaid = false, // Default value
}) : date = date ?? DateTime.now();
}

void main() {
// Can provide parameters in any order
var expense1 = Expense(
amount: 45.00,
description: 'Dinner',
category: 'Food',
notes: 'Birthday dinner',
isPaid: true,
);

// Can skip optional parameters
var expense2 = Expense(
description: 'Coffee',
amount: 4.50,
category: 'Food',
);

// Can provide date if needed
var expense3 = Expense(
description: 'Rent',
amount: 1200.0,
category: 'Bills',
date: DateTime(2025, 10, 1),
);
}









Key Differences:

































Feature Positional []
Named {}
Order matters ✅ Yes ❌ No
More readable ❌ Less ✅ More
Can be required ❌ No ✅ Yes (with required)
Default values ✅ Yes ✅ Yes








Part 5: Default Values



You can provide default values for optional parameters:




class Expense {
String description;
double amount;
String category;
DateTime date;
String currency;
bool isPaid;

Expense({
required this.description,
required this.amount,
this.category = 'Other', // Default: 'Other'
DateTime? date,
this.currency = 'USD', // Default: 'USD'
this.isPaid = false, // Default: false
}) : date = date ?? DateTime.now();

void printDetails() {
String paidStatus = isPaid ? '✅ Paid' : '❌ Unpaid';
print('$description: $currency \$${amount.toStringAsFixed(2)} [$category] - $paidStatus');
}
}

void main() {
// Using all defaults
var expense1 = Expense(
description: 'Mystery purchase',
amount: 25.00,
);

// Override some defaults
var expense2 = Expense(
description: 'Rent',
amount: 1200.0,
category: 'Bills',
isPaid: true,
);

// Override currency
var expense3 = Expense(
description: 'Tokyo hotel',
amount: 15000,
currency: 'JPY',
category: 'Travel',
);

expense1.printDetails();
expense2.printDetails();
expense3.printDetails();
}






Output:




Mystery purchase: USD $25.00 [Other] - ❌ Unpaid
Rent: USD $1200.00 [Bills] - ✅ Paid
Tokyo hotel: JPY $15000.00 [Travel] - ❌ Unpaid












Part 6: Combining Named Constructors with Optional Parameters



The most powerful approach combines both techniques:




class Expense {
String description;
double amount;
String category;
DateTime date;
String? notes;
bool isPaid;

// Regular constructor with named parameters
Expense({
required this.description,
required this.amount,
required this.category,
DateTime? date,
this.notes,
this.isPaid = false,
}) : date = date ?? DateTime.now();

// Named constructor: quick expense (today, unpaid)
Expense.quick(
this.description,
this.amount,
this.category, {
this.notes,
}) : date = DateTime.now(),
isPaid = false;

// Named constructor: monthly bill (bills category, today, paid)
Expense.bill(
this.description,
this.amount, {
this.notes,
}) : category = 'Bills',
date = DateTime.now(),
isPaid = true;

// Named constructor: recurring subscription
Expense.subscription({
required this.description,
required this.amount,
this.notes,
}) : category = 'Entertainment',
date = DateTime.now(),
isPaid = true;

void printDetails() {
String paid = isPaid ? '✅' : '❌';
String noteText = notes != null ? ' - $notes' : '';
print('$paid $description: \$${amount.toStringAsFixed(2)} [$category]$noteText');
}
}

void main() {
print('OCTOBER EXPENSES:\n');

// Different ways to create expenses
var coffee = Expense.quick('Coffee', 4.50, 'Food');

var rent = Expense.bill('Rent', 1200.0, notes: 'October payment');

var netflix = Expense.subscription(
description: 'Netflix',
amount: 15.99,
notes: 'Premium plan',
);

var dinner = Expense(
description: 'Dinner date',
amount: 85.50,
category: 'Food',
notes: 'Anniversary',
);

coffee.printDetails();
rent.printDetails();
netflix.printDetails();
dinner.printDetails();
}






Output:




OCTOBER EXPENSES:

❌ Coffee: $4.50 [Food]
✅ Rent: $1200.00 [Bills] - October payment
✅ Netflix: $15.99 [Entertainment] - Premium plan
❌ Dinner date: $85.50 [Food] - Anniversary












Part 7: Real-World Example - Complete Expense Class



Here's a production-ready Expense class with multiple constructors:




class Expense {
String description;
double amount;
String category;
DateTime date;
String? notes;
bool isPaid;
String paymentMethod;

// Main constructor - full control
Expense({
required this.description,
required this.amount,
required this.category,
DateTime? date,
this.notes,
this.isPaid = false,
this.paymentMethod = 'Cash',
}) : date = date ?? DateTime.now();

// Quick daily expense
Expense.quick(
this.description,
this.amount,
this.category,
) : date = DateTime.now(),
notes = null,
isPaid = false,
paymentMethod = 'Cash';

// Monthly recurring bill
Expense.monthlyBill(
this.description,
this.amount, {
this.paymentMethod = 'Auto-pay',
}) : category = 'Bills',
date = DateTime.now(),
notes = 'Monthly recurring',
isPaid = true;

// Credit card purchase
Expense.creditCard(
this.description,
this.amount,
this.category, {
this.notes,
}) : date = DateTime.now(),
isPaid = false,
paymentMethod = 'Credit Card';

// Cash purchase (already paid)
Expense.cash(
this.description,
this.amount,
this.category, {
this.notes,
}) : date = DateTime.now(),
isPaid = true,
paymentMethod = 'Cash';

// Yesterday's expense (for when you forget to log)
Expense.yesterday(
this.description,
this.amount,
this.category,
) : date = DateTime.now().subtract(Duration(days: 1)),
notes = 'Logged late',
isPaid = true,
paymentMethod = 'Cash';

void printDetails() {
String paid = isPaid ? '✅ Paid' : '❌ Unpaid';
String noteText = notes != null ? '\n Note: $notes' : '';
print('─────────────────────────────');
print('$description');
print('Amount: \$${amount.toStringAsFixed(2)}');
print('Category: $category');
print('Date: ${date.toString().split(' ')[0]}');
print('Payment: $paymentMethod');
print('Status: $paid$noteText');
}

bool isMajorExpense() => amount > 100;

String getSummary() {
String emoji = isMajorExpense() ? '🔴' : '🟢';
return '$emoji \$${amount.toStringAsFixed(2)} - $description [$category]';
}
}

void main() {
print('📊 EXPENSE TRACKER\n');

var expenses = [
Expense.quick('Morning coffee', 4.50, 'Food'),
Expense.monthlyBill('Internet', 59.99),
Expense.creditCard('Groceries', 127.50, 'Food', notes: 'Weekly shopping'),
Expense.cash('Parking', 5.00, 'Transport'),
Expense.yesterday('Lunch', 15.00, 'Food'),
Expense(
description: 'New laptop',
amount: 1299.99,
category: 'Electronics',
paymentMethod: 'Credit Card',
notes: 'Work equipment',
),
];

// Print all summaries
print('Summary:');
for (var expense in expenses) {
print(expense.getSummary());
}

// Print details of major expenses
print('\n\nMAJOR EXPENSES (>\$100):');
for (var expense in expenses) {
if (expense.isMajorExpense()) {
expense.printDetails();
}
}

// Calculate totals
double total = 0;
double unpaid = 0;

for (var expense in expenses) {
total += expense.amount;
if (!expense.isPaid) {
unpaid += expense.amount;
}
}

print('\n─────────────────────────────');
print('💰 Total Expenses: \$${total.toStringAsFixed(2)}');
print('❌ Unpaid: \$${unpaid.toStringAsFixed(2)}');
print('✅ Paid: \$${(total - unpaid).toStringAsFixed(2)}');
}












🎯 Practice Exercises






Exercise 1: Create a Budget Class (Easy)



Create a Budget class with:




  • Properties: category, limit, month, year

  • Regular constructor

  • Named constructor Budget.monthly(category, limit) that uses current month/year



Solution:




class Budget {
String category;
double limit;
int month;
int year;

Budget(this.category, this.limit, this.month, this.year);

Budget.monthly(this.category, this.limit)
: month = DateTime.now().month,
year = DateTime.now().year;

void printDetails() {
print('$category: \$${limit.toStringAsFixed(2)} for $month/$year');
}
}

void main() {
var foodBudget = Budget.monthly('Food', 500.0);
var rentBudget = Budget('Rent', 1200.0, 10, 2025);

foodBudget.printDetails();
rentBudget.printDetails();
}









Exercise 2: Enhanced Expense Creation (Medium)



Add these named constructors to your Expense class:





  1. Expense.splitBill(description, totalAmount, numberOfPeople) - divides amount by number of people


  2. Expense.tip(description, baseAmount, tipPercent) - calculates total with tip


  3. Expense.recurring(description, amount, frequency) - where frequency is 'weekly', 'monthly', or 'yearly'



Solution:




class Expense {
String description;
double amount;
String category;
DateTime date;
String? notes;

Expense(this.description, this.amount, this.category, this.date, {this.notes});

// Split bill constructor
Expense.splitBill(
String desc,
double totalAmount,
int people,
) : description = '$desc (split $people ways)',
amount = totalAmount / people,
category = 'Food',
date = DateTime.now(),
notes = 'Split with $people people';

// Tip calculator constructor
Expense.tip(
String desc,
double baseAmount,
double tipPercent,
) : description = desc,
amount = baseAmount * (1 + tipPercent / 100),
category = 'Food',
date = DateTime.now(),
notes = '${tipPercent}% tip included';

// Recurring expense constructor
Expense.recurring(
this.description,
this.amount,
String frequency,
) : category = 'Bills',
date = DateTime.now(),
notes = 'Recurring: $frequency';
}

void main() {
var dinner = Expense.splitBill('Restaurant dinner', 120.00, 4);
var lunch = Expense.tip('Lunch', 25.00, 20);
var gym = Expense.recurring('Gym membership', 45.00, 'monthly');

print('${dinner.description}: \$${dinner.amount.toStringAsFixed(2)} - ${dinner.notes}');
print('${lunch.description}: \$${lunch.amount.toStringAsFixed(2)} - ${lunch.notes}');
print('${gym.description}: \$${gym.amount.toStringAsFixed(2)} - ${gym.notes}');
}









Exercise 3: Flexible User Class (Hard)



Create a User class for your expense app with:




  • Properties: name, email, currency, monthlyBudget, notifications

  • Main constructor with named parameters (all required except notifications default = true)


  • User.quick(name, email) - uses USD currency, $2000 budget


  • User.premium(name, email, monthlyBudget) - USD currency, notifications on



Solution:




class User {
String name;
String email;
String currency;
double monthlyBudget;
bool notifications;

User({
required this.name,
required this.email,
required this.currency,
required this.monthlyBudget,
this.notifications = true,
});

User.quick(this.name, this.email)
: currency = 'USD',
monthlyBudget = 2000.0,
notifications = true;

User.premium(this.name, this.email, this.monthlyBudget)
: currency = 'USD',
notifications = true;

void printProfile() {
String notif = notifications ? '✅' : '❌';
print('─────────────────');
print('👤 $name');
print('📧 $email');
print('💵 Budget: $currency \$${monthlyBudget.toStringAsFixed(2)}/month');
print('🔔 Notifications: $notif');
}
}

void main() {
var user1 = User.quick('John Doe', '[email protected]');
var user2 = User.premium('Jane Smith', '[email protected]', 3500.0);
var user3 = User(
name: 'Bob Wilson',
email: '[email protected]',
currency: 'EUR',
monthlyBudget: 2500.0,
notifications: false,
);

user1.printProfile();
user2.printProfile();
user3.printProfile();
}












Common Mistakes & How to Fix Them






Mistake 1: Forgetting Initializer List Colon






// ❌ Wrong
Expense.quick(this.description, this.amount, this.category)
date = DateTime.now();

// ✅ Correct - need the colon
Expense.quick(this.description, this.amount, this.category)
: date = DateTime.now();









Mistake 2: Mixing Positional and Named Parameters Incorrectly






// ❌ Wrong - can't mix freely
Expense(this.description, {required this.amount}, this.category);

// ✅ Correct - positional first, then named
Expense(this.description, this.category, {required this.amount});









Mistake 3: Not Using required for Named Parameters






// ❌ Wrong - amount could be null
Expense({this.description, this.amount, this.category});

// ✅ Correct - make required fields explicit
Expense({
required this.description,
required this.amount,
required this.category,
});









Mistake 4: Forgetting this in Named Constructors






// ❌ Wrong
Expense.quick(description, amount, category)
: date = DateTime.now();

// ✅ Correct
Expense.quick(this.description, this.amount, this.category)
: date = DateTime.now();












Key Concepts Review



✅ Named constructors let you create objects in different ways


✅ Initializer lists (:) set properties before object creation


✅ Optional positional parameters use [] brackets


✅ Named parameters use {} curly braces and are more readable


✅ Default values make parameters optional with sensible defaults


✅ required keyword makes named parameters mandatory


✅ Combine techniques for maximum flexibility







Self-Check Questions





1. What's the difference between a regular constructor and a named constructor?



Answer:




  • Regular constructor: Expense(...) - only one per class

  • Named constructor: Expense.quick(...) - can have multiple with different names, each providing different ways to create objects





2. What does the : (colon) mean in a constructor?



Answer:

The colon starts the initializer list, where you can set property values before the constructor body runs. It's used to initialize properties that aren't in the parameter list.





3. When should you use named parameters vs positional parameters?



Answer:





  • Positional: When order is obvious and there are few parameters (2-3)


  • Named: When you have many parameters, some are optional, or readability is important







What's Next?



In Lesson 4: Encapsulation, we'll learn:




  • How to make properties private (with _ underscore)

  • Why we should hide internal data

  • Getters and setters for controlled access

  • Validation to prevent invalid data

  • Keeping our expense data safe!



Example preview:




class Expense {
String _description; // Private!
double _amount; // Private!

// Can't do: expense._amount = -100;
// Must use: expense.setAmount(100);

set amount(double value) {
if (value < 0) {
print('❌ Amount cannot be negative!');
return;
}
_amount = value;
}
}






See you in Lesson 4! 🚀









Additional Resources




  • Try creating constructors for other classes: Category, PaymentMethod, Budget

  • Experiment with combining multiple techniques

  • Think about which constructor style makes your code most readable



Remember: The goal is to make object creation easy and intuitive for whoever uses your class (including future you)! 💪

Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Dart Object Oriented For Beginner : Expense Manager Case Study Part 3

Thematisch verwandte Begriffe: Dart, Object, Oriented, Beginner · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

💬 Kommentare werden geladen…
Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-101901 | Axios is a promise-based HTTP client for the browser and Node.js. From …
Advisory →
tsecurity.de Icon
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag