diff --git a/src/main/kotlin/ru/otus/cars/Car.kt b/src/main/kotlin/ru/otus/cars/Car.kt index 559978c..6d919f2 100644 --- a/src/main/kotlin/ru/otus/cars/Car.kt +++ b/src/main/kotlin/ru/otus/cars/Car.kt @@ -19,6 +19,11 @@ interface Car : CarInput { */ val carOutput: CarOutput + /** + * Используется для заправки машины + */ + val tankMouth: TankMouth + /** * Получить оборудование */ diff --git a/src/main/kotlin/ru/otus/cars/CarOutput.kt b/src/main/kotlin/ru/otus/cars/CarOutput.kt index 875339f..c251dc0 100644 --- a/src/main/kotlin/ru/otus/cars/CarOutput.kt +++ b/src/main/kotlin/ru/otus/cars/CarOutput.kt @@ -8,4 +8,9 @@ interface CarOutput { * Скажи текущую скорость */ fun getCurrentSpeed(): Int + + /** + * Скажи уровень топлива в % от полного бака + */ + fun getFuelLevel(): Int } \ No newline at end of file diff --git a/src/main/kotlin/ru/otus/cars/GasStation.kt b/src/main/kotlin/ru/otus/cars/GasStation.kt new file mode 100644 index 0000000..a4ec3b0 --- /dev/null +++ b/src/main/kotlin/ru/otus/cars/GasStation.kt @@ -0,0 +1,15 @@ +package ru.otus.cars + + +fun fillCar(car: Car, liters: Int) { + try { + car.tankMouth.open() + when (val mouth = car.tankMouth) { + is TankMouth.PETROL -> mouth.fuelPetrol(liters) + is TankMouth.LPG -> mouth.fuelLPG(liters) + } + car.tankMouth.close() + } catch (e: Exception) { + println("При попытке заправиться возникли проблемы: ${e.message}") + } +} diff --git a/src/main/kotlin/ru/otus/cars/Tank.kt b/src/main/kotlin/ru/otus/cars/Tank.kt new file mode 100644 index 0000000..264cf79 --- /dev/null +++ b/src/main/kotlin/ru/otus/cars/Tank.kt @@ -0,0 +1,31 @@ +package ru.otus.cars + +interface FuelSource { + /** + * Получение уровня топлива в % от полного бака + */ + fun getLevel(): Int +} + +interface FuelReceiver { + /** + * Заливка топлива + */ + fun receiveFuel(liters: Int) +} + +class Tank(private val volume: Int): FuelSource, FuelReceiver { + private var currentFuel: Int = 0 + + override fun getLevel(): Int = (currentFuel * 100)/volume + + override fun receiveFuel(liters: Int) { + currentFuel += liters + + if (currentFuel > volume) { + currentFuel = volume + + throw IllegalArgumentException("Бак переполнился") + } + } +} diff --git a/src/main/kotlin/ru/otus/cars/TankMouth.kt b/src/main/kotlin/ru/otus/cars/TankMouth.kt new file mode 100644 index 0000000..4c7b6d7 --- /dev/null +++ b/src/main/kotlin/ru/otus/cars/TankMouth.kt @@ -0,0 +1,39 @@ +package ru.otus.cars + +sealed class TankMouth { + abstract val fuelReceiver: FuelReceiver + private var opened: Boolean = false + abstract val tankType: String + + fun open() { + opened = true + } + + fun close() { + opened = false + } + + protected fun fillReceiver(liters: Int) { + if (!opened) { + throw IllegalStateException("При попытке залить топливо в закрытый $tankType топливо разлилось на землю") + } + + fuelReceiver.receiveFuel(liters) + } + + data class PETROL(override val fuelReceiver: FuelReceiver): TankMouth() { + override val tankType: String = "бак" + + fun fuelPetrol(liters: Int) { + fillReceiver(liters) + } + } + + data class LPG(override val fuelReceiver: FuelReceiver): TankMouth() { + override val tankType: String = "баллон" + + fun fuelLPG(liters: Int) { + fillReceiver(liters) + } + } +} diff --git a/src/main/kotlin/ru/otus/cars/Taz.kt b/src/main/kotlin/ru/otus/cars/Taz.kt index 49df937..607e840 100644 --- a/src/main/kotlin/ru/otus/cars/Taz.kt +++ b/src/main/kotlin/ru/otus/cars/Taz.kt @@ -36,4 +36,15 @@ object Taz: Car { override fun wheelToLeft(degrees: Int) { throw NotImplementedError("Руля нет") } + + /** + * Используется для заправки машины + */ + override val tankMouth: TankMouth + get() = throw IllegalAccessException("При попытке заправиться проскочила искра от рваной проводки и случилось нехорошее") + + // Теперь мы узнаем что это за машина + override fun toString(): String { + return "Старый ржавый Таз" + } } \ No newline at end of file diff --git a/src/main/kotlin/ru/otus/cars/Vaz2107.kt b/src/main/kotlin/ru/otus/cars/Vaz2107.kt index be857d2..f8159fd 100644 --- a/src/main/kotlin/ru/otus/cars/Vaz2107.kt +++ b/src/main/kotlin/ru/otus/cars/Vaz2107.kt @@ -20,6 +20,10 @@ class Vaz2107 private constructor(color: String) : VazPlatform(color) { override fun build(plates: Car.Plates): Vaz2107 = Vaz2107("Зеленый").apply { this.engine = getRandomEngine() this.plates = plates + + val gasTank = Tank(70) + this.gasTank = gasTank + this.tankMouth = TankMouth.LPG(gasTank) } /** @@ -36,6 +40,9 @@ class Vaz2107 private constructor(color: String) : VazPlatform(color) { const val MODEL = "2107" } + override lateinit var gasTank: FuelSource + override lateinit var tankMouth: TankMouth + // Переопределяем свойство родителя override lateinit var engine: VazEngine private set @@ -59,7 +66,7 @@ class Vaz2107 private constructor(color: String) : VazPlatform(color) { // Выводим состояние машины override fun toString(): String { - return "Vaz2107(plates=$plates, wheelAngle=$wheelAngle, currentSpeed=$currentSpeed)" + return "Vaz2107(plates=$plates, wheelAngle=$wheelAngle, currentSpeed=$currentSpeed, currentFuel=${carOutput.getFuelLevel()})" } /** @@ -74,5 +81,9 @@ class Vaz2107 private constructor(color: String) : VazPlatform(color) { override fun getCurrentSpeed(): Int { return this@Vaz2107.currentSpeed } + + override fun getFuelLevel(): Int { + return this@Vaz2107.gasTank.getLevel() + } } } \ No newline at end of file diff --git a/src/main/kotlin/ru/otus/cars/Vaz2108.kt b/src/main/kotlin/ru/otus/cars/Vaz2108.kt index 27b83b8..8bce4b5 100644 --- a/src/main/kotlin/ru/otus/cars/Vaz2108.kt +++ b/src/main/kotlin/ru/otus/cars/Vaz2108.kt @@ -21,6 +21,10 @@ class Vaz2108 private constructor(color: String) : VazPlatform(color) { override fun build(plates: Car.Plates): Vaz2108 = Vaz2108("Красный").apply { this.engine = getRandomEngine() this.plates = plates + + val gasTank = Tank(50) + this.gasTank = gasTank + this.tankMouth = TankMouth.PETROL(gasTank) } fun alignWheels(vaz2108: Vaz2108) { @@ -34,6 +38,9 @@ class Vaz2108 private constructor(color: String) : VazPlatform(color) { const val MODEL = "2108" } + override lateinit var gasTank: FuelSource + override lateinit var tankMouth: TankMouth + // Переопределяем свойство родителя override lateinit var engine: VazEngine private set @@ -63,7 +70,7 @@ class Vaz2108 private constructor(color: String) : VazPlatform(color) { // Выводим состояние машины override fun toString(): String { - return "Vaz2108(plates=$plates, wheelAngle=$wheelAngle, currentSpeed=$currentSpeed)" + return "Vaz2108(plates=$plates, wheelAngle=$wheelAngle, currentSpeed=$currentSpeed, currentFuel=${carOutput.getFuelLevel()})" } /** @@ -78,5 +85,9 @@ class Vaz2108 private constructor(color: String) : VazPlatform(color) { override fun getCurrentSpeed(): Int { return this@Vaz2108.currentSpeed } + + override fun getFuelLevel(): Int { + return this@Vaz2108.gasTank.getLevel() + } } } \ No newline at end of file diff --git a/src/main/kotlin/ru/otus/cars/VazPlatform.kt b/src/main/kotlin/ru/otus/cars/VazPlatform.kt index 079c2da..07a035a 100644 --- a/src/main/kotlin/ru/otus/cars/VazPlatform.kt +++ b/src/main/kotlin/ru/otus/cars/VazPlatform.kt @@ -14,6 +14,8 @@ abstract class VazPlatform(override val color: String) : Car { // Абстрактное свойство двигателя abstract val engine: VazEngine + + abstract val gasTank: FuelSource } // Перечисление двигателей ВАЗ diff --git a/src/main/kotlin/ru/otus/cars/main.kt b/src/main/kotlin/ru/otus/cars/main.kt index 978d0ef..4cd9f6b 100644 --- a/src/main/kotlin/ru/otus/cars/main.kt +++ b/src/main/kotlin/ru/otus/cars/main.kt @@ -16,6 +16,8 @@ fun main() { techChecks() println("\n===> Taz...") println(Taz.color) + println("\n===> go to the gas station...") + refillTank() } fun driveCars() { @@ -90,4 +92,28 @@ fun repairEngine(car: VazPlatform) { is VazEngine.LADA_2107 -> println("Чистка карбюратора у двигателя объемом ${car.engine.volume} куб.см у машины $car") is VazEngine.SAMARA_2108 -> println("Угол зажигания у двигателя объемом ${car.engine.volume} куб.см у машины $car") } +} + + +fun refillTank() { + val cars = listOf( + Vaz2107.build(Car.Plates("123", 77)), + Vaz2108.build(Car.Plates("321", 78)), + Taz + ) + + fillManyCars(cars, 60) +} + +fun fillManyCars(cars: Iterable, liters: Int) { + cars.forEach { car -> + println("Заправляем $car") + fillCar(car, liters) + + try { + println("Теперь в машине ${car.carOutput.getFuelLevel()}% топлива") + } catch (e: Error) { + println("Для $car даже вывести ничего не получается") + } + } } \ No newline at end of file