1#include <iostream>
2#include <string>
3#include <vector>
4
5// Base interface class to enable polymorphism
6class IBase {
7public:
8 virtual ~IBase() =
9 default; // Virtual destructor to ensure proper cleanup of derived classes
10 virtual void status() const = 0; // Pure virtual function to enforce
11 // implementation in derived classes
12};
13
14// ISwitchable Interface, represents an object that can be turned on and off
15class ISwitchable : virtual public IBase {
16public:
17 virtual ~ISwitchable() = default; // Virtual destructor
18 virtual void turnOn() = 0; // Pure virtual function to turn on the object
19 virtual void turnOff() = 0; // Pure virtual function to turn off the object
20 virtual bool
21 isOn() const = 0; // Pure virtual function to check if the object is on
22
23 // Provides status indicating whether the switch is on or off
24 void status() const override {
25 if (isOn())
26 std::cout << "Switch is On" << std::endl;
27 else
28 std::cout << "Switch is Off" << std::endl;
29 }
30};
31
32// IDimmable Interface, represents an object that can adjust brightness
33class IDimmable : virtual public IBase {
34public:
35 virtual ~IDimmable() = default; // Virtual destructor
36 virtual void setBrightness(int level) = 0; // Set the brightness level
37 virtual int getBrightness() const = 0; // Get the brightness level
38
39 // Provides status indicating the brightness level
40 void status() const override {
41 std::cout << "Brightness is: " << getBrightness() << std::endl;
42 }
43};
44
45// IAdjustableTemperature Interface, represents an object that can adjust
46// temperature
47class IAdjustableTemperature : virtual public IBase {
48public:
49 virtual ~IAdjustableTemperature() = default; // Virtual destructor
50 virtual void setTemperature(int temp) = 0; // Set the temperature
51 virtual int getTemperature() const = 0; // Get the current temperature
52
53 // Provides status indicating the temperature level
54 void status() const override {
55 std::cout << "Temperature is: " << getTemperature() << std::endl;
56 }
57};
58
59// LightBulb class implementing ISwitchable interface
60class LightBulb : public ISwitchable {
61private:
62 bool on; // Tracks if the bulb is on
63 int brightness; // Tracks brightness level (though unused here)
64
65public:
66 LightBulb()
67 : on(false), brightness(0) {
68 } // Constructor initializes bulb as off and brightness to 0
69
70 void turnOn() override { on = true; } // Turn the bulb on
71 void turnOff() override { on = false; } // Turn the bulb off
72 bool isOn() const override { return on; } // Check if the bulb is on
73
74 void status() const override {
75 ISwitchable::status();
76 } // Output the on/off status of the bulb
77};
78
79// DimmableBulb class implementing both ISwitchable and IDimmable interfaces
80class DimmableBulb : public ISwitchable, public IDimmable {
81private:
82 bool on; // Tracks if the bulb is on
83 int brightness; // Tracks brightness level
84
85public:
86 DimmableBulb()
87 : on(false), brightness(0) {} // Initialize bulb as off with brightness 0
88
89 void turnOn() override { on = true; } // Turn the bulb on
90 void turnOff() override { on = false; } // Turn the bulb off
91 bool isOn() const override { return on; } // Check if the bulb is on
92
93 // Set brightness level, ensuring it stays between 0 and 100
94 void setBrightness(int level) override {
95 if (level < 0) {
96 brightness = 0;
97 } else if (level > 100) {
98 brightness = 100;
99 } else {
100 brightness = level;
101 }
102 }
103
104 int getBrightness() const override {
105 return brightness;
106 } // Get the current brightness level
107
108 // Print both switch and brightness statuses
109 void status() const override {
110 ISwitchable::status();
111 IDimmable::status();
112 }
113};
114
115// Thermostat class implementing ISwitchable and IAdjustableTemperature
116// interfaces
117class Thermostat : public ISwitchable, public IAdjustableTemperature {
118private:
119 bool on; // Tracks if the thermostat is on
120 int temperature; // Tracks temperature level
121
122public:
123 Thermostat()
124 : on(false), temperature(20) {
125 } // Initialize thermostat as off with default temperature 20
126
127 void turnOn() override { on = true; } // Turn the thermostat on
128 void turnOff() override { on = false; } // Turn the thermostat off
129 bool isOn() const override { return on; } // Check if the thermostat is on
130
131 void setTemperature(int temp) override {
132 temperature = temp;
133 } // Set the desired temperature
134 int getTemperature() const override {
135 return temperature;
136 } // Get the current temperature
137
138 // Print both switch and temperature statuses
139 void status() const override {
140 ISwitchable::status();
141 IAdjustableTemperature::status();
142 }
143};
144
145// Fan class implementing ISwitchable interface
146class Fan : public ISwitchable {
147private:
148 bool on; // Tracks if the fan is on
149
150public:
151 Fan() : on(false) {} // Initialize fan as off
152
153 void turnOn() override { on = true; } // Turn the fan on
154 void turnOff() override { on = false; } // Turn the fan off
155 bool isOn() const override { return on; } // Check if the fan is on
156};
157
158// Main function to demonstrate the system
159int main() {
160 // Create instances of each device
161 LightBulb bulb;
162 DimmableBulb dimBulb;
163 Thermostat thermostat;
164 Fan fan;
165
166 // Polymorphic collection of all devices
167 std::vector<IBase *> allItems;
168 allItems.push_back(&bulb);
169 allItems.push_back(&dimBulb);
170 allItems.push_back(&thermostat);
171 allItems.push_back(&fan);
172
173 // Separate lists of devices by interface type
174 std::vector<ISwitchable *> switchables;
175 std::vector<IAdjustableTemperature *> tempAdjustables;
176 std::vector<IDimmable *> dimmables;
177
178 // Populate interface-specific vectors using dynamic casting
179 for (IBase *item : allItems) {
180 if (auto switchable = dynamic_cast<ISwitchable *>(item)) {
181 switchables.push_back(switchable);
182 }
183 if (auto dimmable = dynamic_cast<IDimmable *>(item)) {
184 dimmables.push_back(dimmable);
185 }
186 if (auto tempAdjustable = dynamic_cast<IAdjustableTemperature *>(item)) {
187 tempAdjustables.push_back(tempAdjustable);
188 }
189 }
190
191 // Max out brightness on all dimmable devices
192 for (auto &dimmable : dimmables)
193 dimmable->setBrightness(100);
194
195 // Set all adjustable temperature devices to 70 degrees
196 for (auto &tempAdjustable : tempAdjustables)
197 tempAdjustable->setTemperature(70);
198
199 // Turn on all switchable devices
200 for (auto &switchable : switchables)
201 switchable->turnOn();
202
203 // Print status of all devices
204 std::cout << "All Statuses:" << std::endl;
205 for (auto &item : allItems)
206 item->status();
207}