diff --git a/src/main/kotlin/ru/otus/cars/Car.kt b/src/main/kotlin/ru/otus/cars/Car.kt index 559978c..2298811 100644 --- a/src/main/kotlin/ru/otus/cars/Car.kt +++ b/src/main/kotlin/ru/otus/cars/Car.kt @@ -7,7 +7,8 @@ interface Car : CarInput { /** * Номерной знак */ - val plates: Plates + // в задании именно CarPlates (никак не Plates) + val plates: CarPlates /** * Цвет машины @@ -27,5 +28,8 @@ interface Car : CarInput { /** * Внутренний статический класс - номерой знак */ - data class Plates(val number: String, val region: Int) + data class CarPlates(val number: String, val region: Int) + + // горловина бака + val tankMouth: TankMouth } \ No newline at end of file diff --git a/src/main/kotlin/ru/otus/cars/CarBuilder.kt b/src/main/kotlin/ru/otus/cars/CarBuilder.kt index 224f46d..ad9cc79 100644 --- a/src/main/kotlin/ru/otus/cars/CarBuilder.kt +++ b/src/main/kotlin/ru/otus/cars/CarBuilder.kt @@ -7,5 +7,5 @@ sealed interface CarBuilder { /** * Собери машину */ - fun build(plates: Car.Plates): Car + fun build(plates: Car.CarPlates): Car } \ No newline at end of file diff --git a/src/main/kotlin/ru/otus/cars/CarFactory.kt b/src/main/kotlin/ru/otus/cars/CarFactory.kt index 3b8f03e..6cb3fdb 100644 --- a/src/main/kotlin/ru/otus/cars/CarFactory.kt +++ b/src/main/kotlin/ru/otus/cars/CarFactory.kt @@ -7,14 +7,14 @@ interface CarFactory { /** * Выпусти машину */ - fun buildCar(builder: CarBuilder, plates: Car.Plates): Car + fun buildCar(builder: CarBuilder, plates: Car.CarPlates): Car } /** * Автозавод в Тольятти (он у нас один такой) */ object Togliatti : CarFactory { - private fun buildVaz2107(plates: Car.Plates): Car { + private fun buildVaz2107(plates: Car.CarPlates): Car { println("Запил ${Vaz2107.MODEL} в Тольятти...") val vaz = Vaz2107.build(plates) println("Проверяем тачку...") @@ -23,7 +23,7 @@ object Togliatti : CarFactory { return vaz } - private fun buildVaz2108(plates: Car.Plates): Car { + private fun buildVaz2108(plates: Car.CarPlates): Car { println("Запил ${Vaz2108.MODEL} в Тольятти...") val vaz = Vaz2108.build(plates) println("Сход-развал...") @@ -32,7 +32,7 @@ object Togliatti : CarFactory { return vaz } - override fun buildCar(builder: CarBuilder, plates: Car.Plates): Car { + override fun buildCar(builder: CarBuilder, plates: Car.CarPlates): Car { return when (builder) { is Vaz2107.Companion -> return buildVaz2107(plates) is Vaz2108.Companion -> return buildVaz2108(plates) diff --git a/src/main/kotlin/ru/otus/cars/CarOutput.kt b/src/main/kotlin/ru/otus/cars/CarOutput.kt index 875339f..30dfab2 100644 --- a/src/main/kotlin/ru/otus/cars/CarOutput.kt +++ b/src/main/kotlin/ru/otus/cars/CarOutput.kt @@ -3,9 +3,11 @@ package ru.otus.cars /** * Следит за машиной */ -interface CarOutput { +interface CarOutput : Tank { /** * Скажи текущую скорость */ fun getCurrentSpeed(): Int + // Остаток в баке + fun getFuelContents() : Int } \ No newline at end of file diff --git a/src/main/kotlin/ru/otus/cars/FuelType.kt b/src/main/kotlin/ru/otus/cars/FuelType.kt new file mode 100644 index 0000000..746fbb9 --- /dev/null +++ b/src/main/kotlin/ru/otus/cars/FuelType.kt @@ -0,0 +1,7 @@ +package ru.otus.cars + +// Список допустимого топлива +enum class FuelType (val fuelType: String) { + PETROL("Бензин"), + LPG("Сжиженный газ") + } \ 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..0254cf2 --- /dev/null +++ b/src/main/kotlin/ru/otus/cars/GasStation.kt @@ -0,0 +1,52 @@ +package ru.otus.cars + +import ru.otus.cars.Taz.tankMouth +import kotlin.random.Random + +// АЗС, заправляет любым топливом +class GasStation { + // заправка машины топливом + fun fuelCar(car: Car) { + // защищенный блок, процесс заправки НЕ должен "взрываться" + try { + println("Топлива до заправки: ${car.carOutput.getFuelContents()}") + when (car.tankMouth.fuelType) { + FuelType.PETROL -> fuelPetrol(car.tankMouth as PetrolMouth, Random.nextInt(0, 100)) + FuelType.LPG -> fuelLpg(car.tankMouth as LpgMouth, Random.nextInt(0, 100)) + } + println("Топлива после заправки: ${car.carOutput.getFuelContents()}") + } catch (t: Throwable) { + println("Ошибка: ${t.message}") + } + + } + // заправка именно бензином, снаружи НЕ доступна + private fun fuelPetrol(tankMouth: PetrolMouth, liters: Int) { + tankMouth.fuelPetrol(liters) + } + // заправка именно сжиженным газом, снаружи НЕ доступна + private fun fuelLpg(tankMouth: LpgMouth, liters: Int) { + tankMouth.fuelLpg(liters) + } + + fun showCarsInfo(cars: List){ + cars.forEach { car: Car -> println(car.getEquipment()) + } + } + + // заправка нескольких машин топливом + fun fuelCars(carList: List) { + println("") + println("Инфо до заправки") + println("-------------------------------------------------------------------------") + showCarsInfo(cars = carList) + println("-------------------------------------------------------------------------") + println("Заправка") + for(car: Car in carList){ + fuelCar(car) + } + println("-------------------------------------------------------------------------") + println("Инфо после заправки") + showCarsInfo(cars = carList) + } +} \ No newline at end of file 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..827ddbc --- /dev/null +++ b/src/main/kotlin/ru/otus/cars/Tank.kt @@ -0,0 +1,9 @@ +package ru.otus.cars + +// Бак +interface Tank { + // Остаток в баке + fun getContenst() : Int + // Изменить остаток в баке + fun reciveFuel(liters: Int) +} \ No newline at end of file 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..294a62a --- /dev/null +++ b/src/main/kotlin/ru/otus/cars/TankMouth.kt @@ -0,0 +1,64 @@ +package ru.otus.cars + +// Топливная система - включает в себя горловину и бак (как наследника бака) +abstract class TankMouth(val value: FuelType): Tank { + init { + println("Тип топливной системы: ${value}") + } + // Допустимый тип топлива + val fuelType: FuelType = value + // Текущий объем топлива (литры) + var currentFuel: Int = 0 + // Открыть + fun open() { + println("Горловина открыта") + } + // Закрыть + fun close() { + println("Горловина закрыта") + } + // текущий остаток топлива + override fun getContenst() : Int { + return this.currentFuel + } + // заправка топливом + override fun reciveFuel(liters: Int) { + this.currentFuel += liters + } +} + +class CustomException(message: String) : Exception(message) + +// Топливная система на бензине +class PetrolMouth : TankMouth(FuelType.PETROL) { + // Заправка бензином + fun fuelPetrol(liters: Int) { + if (fuelType != FuelType.PETROL) { + throw CustomException("Недопустимый тип топлива") + } + // Открыть бак + this.open() + // Заправим бак + this.reciveFuel(liters) + println("заправлено: ${liters}, всего в баке ${this.currentFuel}") + // Закрыть бак + this.close() + } +} + +// Топливная система на сжиженном газе +class LpgMouth : TankMouth(FuelType.LPG) { + fun fuelLpg(liters: Int) { + if (fuelType != FuelType.LPG) { + throw CustomException("Недопустимый тип топлива") + } + // Открыть бак + this.open() + // Заправим бак + this.reciveFuel(liters) + println("заправлено: ${liters}, всего в баке ${this.currentFuel}") + // Закрыть бак + this.close() + } +} + diff --git a/src/main/kotlin/ru/otus/cars/Taz.kt b/src/main/kotlin/ru/otus/cars/Taz.kt index 49df937..1252a1a 100644 --- a/src/main/kotlin/ru/otus/cars/Taz.kt +++ b/src/main/kotlin/ru/otus/cars/Taz.kt @@ -4,7 +4,7 @@ object Taz: Car { /** * Номерной знак */ - override val plates: Car.Plates + override val plates: Car.CarPlates get() = throw NotImplementedError("Номера сняты") /** @@ -36,4 +36,9 @@ object Taz: Car { override fun wheelToLeft(degrees: Int) { throw NotImplementedError("Руля нет") } + + // Горловина + override val tankMouth: TankMouth + get() = throw NotImplementedError("Топливной системы нет") + } \ 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..7e02107 100644 --- a/src/main/kotlin/ru/otus/cars/Vaz2107.kt +++ b/src/main/kotlin/ru/otus/cars/Vaz2107.kt @@ -17,9 +17,10 @@ class Vaz2107 private constructor(color: String) : VazPlatform(color) { } } - override fun build(plates: Car.Plates): Vaz2107 = Vaz2107("Зеленый").apply { + override fun build(plates: Car.CarPlates): Vaz2107 = Vaz2107("Зеленый").apply { this.engine = getRandomEngine() this.plates = plates + this.tankMouth = LpgMouth() // топливная система = сжиженный газ } /** @@ -54,7 +55,7 @@ class Vaz2107 private constructor(color: String) : VazPlatform(color) { * Доступно сборщику * @see [build] */ - override lateinit var plates: Car.Plates + override lateinit var plates: Car.CarPlates private set // Выводим состояние машины @@ -74,5 +75,22 @@ class Vaz2107 private constructor(color: String) : VazPlatform(color) { override fun getCurrentSpeed(): Int { return this@Vaz2107.currentSpeed } + + override fun getContenst(): Int { + return this@Vaz2107.tankMouth.getContenst() + } + + override fun getFuelContents(): Int { + return this@Vaz2107.tankMouth.getContenst() + } + + override fun reciveFuel(liters: Int) { + this@Vaz2107.tankMouth.reciveFuel(liters) + } } + + // Топливная система будет определена при установке на авто + override lateinit var tankMouth: TankMouth + private set + } \ 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..bbd2035 100644 --- a/src/main/kotlin/ru/otus/cars/Vaz2108.kt +++ b/src/main/kotlin/ru/otus/cars/Vaz2108.kt @@ -18,9 +18,10 @@ class Vaz2108 private constructor(color: String) : VazPlatform(color) { } } - override fun build(plates: Car.Plates): Vaz2108 = Vaz2108("Красный").apply { + override fun build(plates: Car.CarPlates): Vaz2108 = Vaz2108("Красный").apply { this.engine = getRandomEngine() this.plates = plates + this.tankMouth = PetrolMouth() // топливная система = бензин } fun alignWheels(vaz2108: Vaz2108) { @@ -58,7 +59,7 @@ class Vaz2108 private constructor(color: String) : VazPlatform(color) { * Доступно сборщику * @see [build] */ - override lateinit var plates: Car.Plates + override lateinit var plates: Car.CarPlates private set // Выводим состояние машины @@ -78,5 +79,19 @@ class Vaz2108 private constructor(color: String) : VazPlatform(color) { override fun getCurrentSpeed(): Int { return this@Vaz2108.currentSpeed } + override fun getContenst(): Int { + return this@Vaz2108.tankMouth.getContenst() + } + + override fun getFuelContents(): Int { + return this@Vaz2108.tankMouth.getContenst() + } + + override fun reciveFuel(liters: Int) { + this@Vaz2108.tankMouth.reciveFuel(liters) + } } + + // Горловина + override lateinit var tankMouth: TankMouth } \ 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..283ce6e 100644 --- a/src/main/kotlin/ru/otus/cars/VazPlatform.kt +++ b/src/main/kotlin/ru/otus/cars/VazPlatform.kt @@ -10,8 +10,7 @@ abstract class VazPlatform(override val color: String) : Car { override fun wheelToLeft(degrees: Int) { wheelAngle -= degrees } // Получить оборудование - override fun getEquipment(): String = "Кузов, колеса, движок" - + override fun getEquipment(): String = "Кузов, колеса, движок, топлива ${tankMouth.getContenst()}" // Абстрактное свойство двигателя abstract val engine: VazEngine } diff --git a/src/main/kotlin/ru/otus/cars/main.kt b/src/main/kotlin/ru/otus/cars/main.kt index 978d0ef..e250cb8 100644 --- a/src/main/kotlin/ru/otus/cars/main.kt +++ b/src/main/kotlin/ru/otus/cars/main.kt @@ -16,11 +16,25 @@ fun main() { techChecks() println("\n===> Taz...") println(Taz.color) + + println("\nЗаправка") + fuelCars() +} + +// заправка нескольких машин топливом +fun fuelCars() { + // список машин через переменные - для читабельности + val vaz1 = Vaz2107.build(Car.CarPlates("123", 77)) + val vaz2 = Vaz2108.build(Car.CarPlates("321", 78)) + val carList = listOf(vaz1, vaz2, Taz) + val gasStation = GasStation() + // заправляем машины списком + gasStation.fuelCars(carList) } fun driveCars() { - val vaz1 = Togliatti.buildCar(Vaz2107, Car.Plates("123", 77)) - val vaz2 = Togliatti.buildCar(Vaz2108, Car.Plates("321", 78)) + val vaz1 = Togliatti.buildCar(Vaz2107, Car.CarPlates("123", 77)) + val vaz2 = Togliatti.buildCar(Vaz2108, Car.CarPlates("321", 78)) println("Экземпляры класса имеют разное внутреннее состояние:") vaz1.wheelToRight(10) @@ -30,7 +44,7 @@ fun driveCars() { } fun innerNestedCheck() { - val vaz = Vaz2107.build(Car.Plates("123", 77)) + val vaz = Vaz2107.build(Car.CarPlates("123", 77)) val output = vaz.VazOutput() // Создаем новый объект ИЗ ЭКЗЕМПЛЯРА МАШИНЫ println("Скорость до проверки: ${output.getCurrentSpeed()}") // Выводит 0 @@ -41,21 +55,21 @@ fun innerNestedCheck() { fun garageMake() { val maker = "Дядя Вася" val garage = object : CarFactory { - override fun buildCar(builder: CarBuilder, plates: Car.Plates): Car { + override fun buildCar(builder: CarBuilder, plates: Car.CarPlates): Car { println("Запил Жигулей у: $maker...") println("Машину не проверяем... и в продакшн...") return builder.build(plates) } } - val vaz = garage.buildCar(Vaz2107, Car.Plates("500", 50)) + val vaz = garage.buildCar(Vaz2107, Car.CarPlates("500", 50)) println(vaz.toString()) } fun getEquipment() { val cars = listOf( - Vaz2107.build(Car.Plates("123", 77)), - Vaz2108.build(Car.Plates("321", 78)) + Vaz2107.build(Car.CarPlates("123", 77)), + Vaz2108.build(Car.CarPlates("321", 78)) ) cars.forEach { car -> @@ -65,8 +79,8 @@ fun getEquipment() { fun getColor() { val cars = listOf( - Vaz2107.build(Car.Plates("123", 77)), - Vaz2108.build(Car.Plates("321", 78)) + Vaz2107.build(Car.CarPlates("123", 77)), + Vaz2108.build(Car.CarPlates("321", 78)) ) cars.forEach { car -> @@ -75,8 +89,8 @@ fun getColor() { } fun techChecks() { - val vaz1 = Vaz2107.build(Car.Plates("123", 77)) - val vaz2 = Vaz2108.build(Car.Plates("321", 78)) + val vaz1 = Vaz2107.build(Car.CarPlates("123", 77)) + val vaz2 = Vaz2108.build(Car.CarPlates("321", 78)) repairEngine(vaz1) repairEngine(vaz2) @@ -90,4 +104,4 @@ fun repairEngine(car: VazPlatform) { is VazEngine.LADA_2107 -> println("Чистка карбюратора у двигателя объемом ${car.engine.volume} куб.см у машины $car") is VazEngine.SAMARA_2108 -> println("Угол зажигания у двигателя объемом ${car.engine.volume} куб.см у машины $car") } -} \ No newline at end of file +}