This commit is contained in:
2026-03-27 21:04:40 +07:00
parent 9e868dcb17
commit 41b38f177f

View File

@@ -1,96 +1,122 @@
// A Mixin: Adds specific behavior without being a parent class
mixin Connectable { mixin Connectable {
bool isConnected = false; bool isConnected = false;
void toggleConnection() => isConnected = !isConnected; void toggleConnection() => isConnected = !isConnected;
} }
abstract class SmartDevice { abstract class SmartDevice {
final String id; // Final: Set once final String id;
String _name; // Private field (starts with _) String _name;
bool _powerStatus = false; 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 // 1. Standard Constructor with named parameters
SmartDevice(this.id, this._name); SmartDevice({required this.id, required String name}) : _name = name;
// 2. Named Constructor // 2. Named Constructor: Preset for Office use
SmartDevice.temp(this.id) : _name = "Unknown Device"; SmartDevice.office({required this.id})
: _name = "Office Desk Lamp",
_auto_on_off = true;
// 3. Factory Constructor: Decides which subclass to return // 3. Named Constructor: Preset for Eco mode
factory SmartDevice.create(String type, String id, String name) { SmartDevice.eco({required this.id})
if (type == 'light') return SmartLight(id, name); : _name = "Eco Saver Unit",
return SmartSpeaker(id, name); _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; String get name => _name;
set name(String value) => _name = value.trim(); set name(String value) => _name = value.trim();
// Abstract method: Must be implemented by children
void performAction(); void performAction();
// Regular method
void togglePower() { void togglePower() {
_powerStatus = !_powerStatus; _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 { class SmartLight extends SmartDevice {
int brightness = 100; int brightness = 100;
// Uses 'super' to pass data to the parent constructor // Using 'super' syntax with named parameters
SmartLight(super.id, super.name); 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 @override
void performAction() { 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 { class SmartSpeaker extends SmartDevice with Connectable {
double volume; double volume;
// 4. Initializer List: Sets volume before the constructor body runs SmartSpeaker({
SmartSpeaker(String id, String name, {this.volume = 0.5}) required String id,
: assert(volume >= 0 && volume <= 1.0), required String name,
super(id, name); this.volume = 0.5,
}) : assert(volume >= 0 && volume <= 1.0),
// 5. Redirecting Constructor: Forwards to the main constructor super(id: id, name: name);
SmartSpeaker.loud(String id, String name) : this(id, name, volume: 1.0);
@override @override
void performAction() { void performAction() {
print('Playing music at ${volume * 100}% volume. WiFi: $isConnected'); print('[$_name] Volume: ${(volume * 100).toInt()}%. Connected: $isConnected');
} }
} }
void main() { void main() {
// Using the Factory // --- USAGE ---
final myLight = SmartDevice.create('light', 'L1', 'Living Room Lamp');
// Using the Redirecting Constructor // 1. Using the 'Office' preset with named ID
final partySpeaker = SmartSpeaker.loud('S1', 'Bass Blaster'); final workLamp = SmartLight.office(id: 'OFFICE_01');
myLight.togglePower(); // Parent method // 2. Using the 'Eco' preset with named ID
partySpeaker.toggleConnection(); // Mixin method final ecoLight = SmartLight.eco(id: 'ECO_99');
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. Lets break down the rationale and real-world use cases for the structure I built. // You're absolutely right. Understanding *why* we use these features is more important than just knowing the syntax. Lets break down the rationale and real-world use cases for the structure I built.
// --- // ---