interface Switchable { val isOn: Boolean fun turnOn() fun turnOff() fun toggle() = if (isOn) turnOff() else turnOn() } interface Lockable { val isLocked: Boolean fun lock() fun unlock() fun securityMessage() = if (isLocked) "secure" else "unlocked" } abstract class SmartDevice( val name: String, val room: String ) { init { require(name.isNotBlank()) { "Device name cannot be blank" } require(room.isNotBlank()) { "Room cannot be blank" } } abstract fun status(): String open fun description(): String = "$name in $room" } class SmartLight( name: String, room: String, initialBrightness: Int = 50 ) : SmartDevice(name, room), Switchable { override var isOn = false private set var brightness = initialBrightness private set init { require(initialBrightness in 0..100) { "Brightness must be from 0 to 100" } } override fun turnOn() { isOn = true } override fun turnOff() { isOn = false } fun setBrightness(level: Int) { require(level in 0..100) { "Brightness must be from 0 to 100" } brightness = level if (level == 0) turnOff() else turnOn() } override fun status() = if (isOn) "ON at $brightness%" else "OFF" override fun description() = "${super.description()} — dimmable light" } class SmartFan( name: String, room: String, initialSpeed: Int = 1 ) : SmartDevice(name, room), Switchable { override var isOn = false private set var speed = initialSpeed private set init { require(initialSpeed in 1..3) { "Speed must be from 1 to 3" } } override fun turnOn() { isOn = true } override fun turnOff() { isOn = false } fun setSpeed(newSpeed: Int) { require(newSpeed in 1..3) { "Speed must be from 1 to 3" } speed = newSpeed } override fun status() = if (isOn) "ON at speed $speed" else "OFF" override fun description() = "${super.description()} — three-speed fan" } class SmartDoorLock( name: String, room: String ) : SmartDevice(name, room), Lockable { override var isLocked = true private set override fun lock() { isLocked = true } override fun unlock() { isLocked = false } override fun status() = if (isLocked) "LOCKED" else "UNLOCKED" override fun description() = "${super.description()} — smart lock" } class SmartHome(private val homeName: String) { private val devices = mutableListOf() fun add(device: SmartDevice) { devices += device } fun dashboard() { println("== $homeName ==") devices.forEach { device -> println("${device.description()}: ${device.status()}") } } fun goodNight() { devices.filterIsInstance().forEach { it.turnOff() } devices.filterIsInstance().forEach { it.lock() } } } fun main() { val lamp = SmartLight("Desk lamp", "Bedroom", 70) val fan = SmartFan("Ceiling fan", "Living room", 2) val door = SmartDoorLock("Front door", "Entrance") val home = SmartHome("Oak House") home.add(lamp) home.add(fan) home.add(door) val switchableDevices: List = listOf(lamp, fan) switchableDevices.forEach { it.turnOn() } lamp.setBrightness(40) fan.setSpeed(3) door.unlock() home.dashboard() println("\nGood-night routine...") home.goodNight() home.dashboard() }