From 41b38f177f38668a3b4d50cae1fc5d7d6f4fe8c4 Mon Sep 17 00:00:00 2001 From: narawat Date: Fri, 27 Mar 2026 21:04:40 +0700 Subject: [PATCH] update --- dart_ex_1/ex_2.dart | 118 +++++++++++++++++++++++++++----------------- 1 file changed, 72 insertions(+), 46 deletions(-) diff --git a/dart_ex_1/ex_2.dart b/dart_ex_1/ex_2.dart index bc352fb..53d6de4 100644 --- a/dart_ex_1/ex_2.dart +++ b/dart_ex_1/ex_2.dart @@ -1,96 +1,122 @@ -// A Mixin: Adds specific behavior without being a parent class mixin Connectable { bool isConnected = false; void toggleConnection() => isConnected = !isConnected; } abstract class SmartDevice { - final String id; // Final: Set once - String _name; // Private field (starts with _) + final String id; + String _name; bool _powerStatus = false; + bool _auto_on_off = false; - static const String brand = "GeminiHome"; // Static: Shared by all instances + static const String brand = "GeminiHome"; - // 1. Generative Constructor - SmartDevice(this.id, this._name); + // 1. Standard Constructor with named parameters + SmartDevice({required this.id, required String name}) : _name = name; - // 2. Named Constructor - SmartDevice.temp(this.id) : _name = "Unknown Device"; + // 2. Named Constructor: Preset for Office use + SmartDevice.office({required this.id}) + : _name = "Office Desk Lamp", + _auto_on_off = true; - // 3. Factory Constructor: Decides which subclass to return - factory SmartDevice.create(String type, String id, String name) { - if (type == 'light') return SmartLight(id, name); - return SmartSpeaker(id, name); + // 3. Named Constructor: Preset for Eco mode + SmartDevice.eco({required this.id}) + : _name = "Eco Saver Unit", + _powerStatus = false, + _auto_on_off = true; + + // 4. Factory Constructor using named parameters + factory SmartDevice.create({ + required String type, + required String id, + required String name, + }) { + if (type == 'light') return SmartLight(id: id, name: name); + return SmartSpeaker(id: id, name: name); + } + + // Specialized factory for the Office preset + factory SmartDevice.createOffice({required String id}) { + return SmartLight.office(id: id); } - // Getter and Setter String get name => _name; set name(String value) => _name = value.trim(); - // Abstract method: Must be implemented by children void performAction(); - // Regular method void togglePower() { _powerStatus = !_powerStatus; - print('$_name is now ${_powerStatus ? "ON" : "OFF"}'); + print('$_name is now ${_powerStatus ? "ON" : "OFF"} (Auto-mode: $_auto_on_off)'); } } - - class SmartLight extends SmartDevice { int brightness = 100; - // Uses 'super' to pass data to the parent constructor - SmartLight(super.id, super.name); + // Using 'super' syntax with named parameters + SmartLight({required super.id, required super.name}); + + // Redirecting to parent named constructors + SmartLight.office({required String id}) : super.office(id: id); + + SmartLight.eco({required String id}) : super.eco(id: id); @override void performAction() { - print('Adjusting brightness to $brightness%'); + print('[$_name] Brightness: $brightness%'); } } - - - -// 'with Connectable' adds the toggleConnection() method to this class class SmartSpeaker extends SmartDevice with Connectable { double volume; - // 4. Initializer List: Sets volume before the constructor body runs - SmartSpeaker(String id, String name, {this.volume = 0.5}) - : assert(volume >= 0 && volume <= 1.0), - super(id, name); - - // 5. Redirecting Constructor: Forwards to the main constructor - SmartSpeaker.loud(String id, String name) : this(id, name, volume: 1.0); + SmartSpeaker({ + required String id, + required String name, + this.volume = 0.5, + }) : assert(volume >= 0 && volume <= 1.0), + super(id: id, name: name); @override void performAction() { - print('Playing music at ${volume * 100}% volume. WiFi: $isConnected'); + print('[$_name] Volume: ${(volume * 100).toInt()}%. Connected: $isConnected'); } } - - - void main() { - // Using the Factory - final myLight = SmartDevice.create('light', 'L1', 'Living Room Lamp'); + // --- USAGE --- + + // 1. Using the 'Office' preset with named ID + final workLamp = SmartLight.office(id: 'OFFICE_01'); - // Using the Redirecting Constructor - final partySpeaker = SmartSpeaker.loud('S1', 'Bass Blaster'); + // 2. Using the 'Eco' preset with named ID + final ecoLight = SmartLight.eco(id: 'ECO_99'); - myLight.togglePower(); // Parent method - partySpeaker.toggleConnection(); // Mixin method - partySpeaker.performAction(); // Overridden method + // 3. Standard creation using clear labels for ID and Name + final customLight = SmartLight(id: 'CUST_01', name: 'My Custom Light'); + + // 4. Using the factory with named parameters + final speaker = SmartDevice.create( + type: 'speaker', + id: 'SPK_01', + name: 'Living Room Bass' + ); + + print('--- Testing Presets ---'); + workLamp.performAction(); + workLamp.togglePower(); + + print(''); + + ecoLight.performAction(); + ecoLight.togglePower(); + + print(''); + speaker.performAction(); } - - - // You're absolutely right. Understanding *why* we use these features is more important than just knowing the syntax. Let’s break down the rationale and real-world use cases for the structure I built. // ---