5. Изучите подклассы и наследование

В этом задании вы узнаете, как работают подклассы и наследование в Kotlin. Они похожи на то, что вы видели в других языках, но есть и некоторые отличия.

openВ Kotlin по умолчанию классы не могут быть унаследованы. Для разрешения наследования класса необходимо пометить его как ` <class>`. В таких подклассах также необходимо пометить свойства и переменные-члены как open`<class>`, чтобы переопределить их в подклассе. openКлючевое слово `<class>` обязательно, чтобы предотвратить случайную утечку деталей реализации в определении класса.

Шаг 1: Откройте класс «Аквариум».

На этом шаге вы создаёте Aquariumкласс open, чтобы затем переопределить его на следующем шаге.

  1. Пометьте Aquariumкласс и все его свойства ключевым openсловом.
open class Aquarium (open var length: Int = 100, open var width: Int = 20, open var height: Int = 40) {
    open var volume: Int
        get() = width * height * length / 1000
        set(value) {
            height = (value * 1000) / (width * length)
        }
  1. Добавьте открытое shapeсвойство со значением "rectangle".
   open val shape = "rectangle"
  1. Добавьте открытое waterсвойство с геттером, который возвращает 90% объема Aquarium.
    open var water: Double = 0.0
        get() = volume * 0.9
  1. Добавьте в метод код printSize()для вывода фигуры и количества воды в процентах от объема.
fun printSize() {
    println(shape)
    println("Width: $width cm " +
            "Length: $length cm " +
            "Height: $height cm ")
    // 1 l = 1000 cm^3
    println("Volume: $volume liters Water: $water liters (${water / volume * 100.0}% full)")
}
  1. В buildAquarium()коде измените его так, чтобы он создавал объект Aquariumс параметрами width = 25, length = 25, и height = 40.
fun buildAquarium() {
    val aquarium6 = Aquarium(length = 25, width = 25, height = 40)
    aquarium6.printSize()
}
  1. Запустите программу и посмотрите на новый результат.
⇒ aquarium initializing
rectangle
Width: 25 cm Length: 25 cm Height: 40 cm 
Volume: 25 liters Water: 22.5 liters (90.0% full)

Шаг 2: Создайте подкласс

  1. Создайте подкласс с Aquariumименем TowerTank, который реализует резервуар в форме закругленного цилиндра вместо прямоугольного. Вы можете добавить его TowerTankниже Aquarium, поскольку в том же файле, что и этот класс, можно добавить еще один класс Aquarium.
  2. В подклассе TowerTankследует переопределить heightсвойство, определенное в конструкторе. Для переопределения свойства используйте overrideключевое слово в подклассе.
  1. Сделайте так, чтобы конструктор TowerTankпринимал значение diameter. Используйте это значение diameterкак для, так lengthи widthдля при вызове конструктора в Aquariumсуперклассе.
class TowerTank (override var height: Int, var diameter: Int): Aquarium(height = height, width = diameter, length = diameter) {
  1. Для вычисления объема цилиндра необходимо переопределить свойство volume. Формула для цилиндра: π, умноженное на квадрат радиуса, умноженное на высоту. Обратите внимание, что IntelliJ может пометить PI как неопределенное значение. Вам необходимо импортировать константу PIиз java.lang.Mathв верхней части файла Main.kt.
    override var volume: Int
    // ellipse area = π * r1 * r2
    get() = (width/2 * length/2 * height / 1000 * PI).toInt()
    set(value) {
        height = ((value * 1000 / PI) / (width/2 * length/2)).toInt()
    }
  1. В этом случае TowerTankизмените значение waterсвойства, установив его равным 80% от объема.
override var water = volume * 0.8
  1. Переопределите значение shapeпо умолчанию "cylinder".
override val shape = "cylinder"
  1. Итоговый код вашего TowerTankкласса должен выглядеть примерно так, как показано ниже.

Aquarium.kt:

package example.myapp

import java.lang.Math.PI

... // existing Aquarium class

class TowerTank (override var height: Int, var diameter: Int): Aquarium(height = height, width = diameter, length = diameter) {
    override var volume: Int
    // ellipse area = π * r1 * r2
    get() = (width/2 * length/2 * height / 1000 * PI).toInt()
    set(value) {
        height = ((value * 1000 / PI) / (width/2 * length/2)).toInt()
    }

    override var water = volume * 0.8
    override val shape = "cylinder"
}
  1. В файле buildAquarium()создайте объект TowerTankдиаметром 25 см и высотой 45 см. Распечатайте его размеры.

Main.kt:

package example.myapp

fun buildAquarium() {
    val myAquarium = Aquarium(width = 25, length = 25, height = 40)
    myAquarium.printSize()
    val myTower = TowerTank(diameter = 25, height = 40)
    myTower.printSize()
}
  1. Запустите свою программу и посмотрите на результат.
⇒ aquarium initializing
rectangle
Width: 25 cm Length: 25 cm Height: 40 cm 
Volume: 25 liters Water: 22.5 liters (90.0% full)
aquarium initializing
cylinder
Width: 25 cm Length: 25 cm Height: 40 cm 
Volume: 18 liters Water: 14.4 l (80.0% full)

Последнее изменение: Воскресенье, 5 апреля 2026, 14:09