Перейти к содержанию

🗒 Задача

Опиши класс для корабля в мобильной игре. Поля хранят имя, среднюю скорость и порт приписки.

Имя корабля менять нельзя, при попытке перезаписать имя в консоль должно выводиться предупреждение.

Создай экземпляр класса и протестируй работу.

❌ Ошибки

  • печатают предупреждение и одновременно присваивают значение свойству

✏️ Комментарии

Такое расположение скобок нарушает конвенции стиля написания)
https://kotlinlang.org/docs/coding-conventions.html#formatting
field не нужно ничего присваивать, а только лишь печатать предупреждение
getter тут вообще не нужен, будет использовать тот, который по умолчанию создается под капотом. Переопределяем только setter
Предлагаю опустить фигурные скобки и через “=” сразу вызывать печать предупреждения.
Ок, только согласно стилистике в перечислении свойств пустые строки не оставляем
Окей, тут надо до конца понять что такое сеттеры и геттеры. Это специальные методы, которые неявно под капотом вызываются, когда пытаемся прочитать перменную (геттер) и когда ей пытаемся что-то присвоить (сеттер).
Их можно прописать явно и даже изменить их поведение, что и требуется в этой задаче.

Что тут происходит:

**1.** создался экземпляр класса лодки
val boat = Boat()
Внутри него есть свойство, которое для ВСЕХ экземпляров будет задавать вот это имя
var name = "Чёрная жемчужина"

**2.** Удали сеттер сначала и посмотри. Каждый раз будет присваиваться новое имя, которое ты задаешь в мейне. Потому что стандартный сеттер отрабатывает под капотом (мы его не видим, но он есть) по умолчанию. Он выглядит так:
*var name = "Чёрная жемчужина"
        set(value) {
                field = value
}*
Помнишь в предыдущих тасках надо было прописать сеттеры и геттеры по умолчанию? Вот это оно. Если пропишешь так, все будет записываться как ожидаешь.

**3.** В текущей задаче надо модифицировать стандартное поведение сеттера. Поэтому сначала прописываем его явно и **удаляем** строку *field = value*.

То есть переданное тобой в мейне вэлью не будет записываться в филд (это ключевые слова описывающие переменные, о них в видео говорил). И все по сути – теперь ничего кроме первичного проинициализированного значения не будет записано в переменную name. Как была Черная Жемчужина при создании объекта, так она и останется.

Только дополнительно мы еще при попытке что-то записать в перменную выбрасываем сообщение "так нельзя".

🧾 Решение

fun main() {
    val ship = Ship( 35, "Spb")
    ship.middleSpeed = 40
    ship.homePort = "Ptz"
    ship.name = "AnotherShip"
    println(ship.name)
}

class Ship(
    var middleSpeed: Int,
    var homePort: String,
) {
    var name: String = "Spb"
        set(value) {
            println("Имя корабля менять нельзя!")
        }
}