Шаг 171.
Основы Kotlin.
Наследование. Приведение типа

    На этом шаге мы приведем некоторые замечания, касающиеся приведения типов.

    Проверка типа не всегда возвращает полезный ответ. Например, параметр any в функции printIsSourceOfBlesings() говорит нам о том, что передаваемый аргумент будет иметь тип Any, но тип Any не уточняет, что с этим аргументом можно делать.

    Приведение типа позволяет обращаться к объекту так, как будто он - экземпляр другого типа. Это позволяет манипулировать объектом, как если бы его тип был объявлен явно (например, вызывать его функции).

    В функции printIsSourceOfBlesings() условный оператор проверяет тип аргумента any, сравнивая его с типом Player. Если условие не выполняется, управление передается в ветвь else.

    Код в ветви else ссылается на переменную name:

fun printIsSourceOfBlessings(any: Any) {
    val isSourceOfBlessings = if (any is Player) {
        any.isBlessed
    } else {
        (any as Room).name == "Fount of Blessings"
    }
    println("$any is a source of blessings: $isSourceOfBlessings")
}

    Оператор as обозначает приведение типа. Он говорит нам: "Чтобы выполнить это выражение, переменную any следует считать экземпляром типа Room". Выражение в данном случае - это ссылка на свойство name класса Room, значение которого сравнивается со строкой "Fount of Blessings".

    Приведение типов - это сила, а с силой приходит ответственность: применять его необходимо осторожно. Примером безопасного применения может служить приведение значения типа Int к более точному числовому типу, например Long.

    Приведение в printIsSourceOfBlesings() работает, но оно небезопасно. Почему? Room, Player, TownSquare - это все классы в NyetHack, поэтому можно предположить, что если any имеет тип, отличный от Player, значит, он имеет тип Room.

    На данный момент это так. Но что будет, если мы добавим новый класс в NyetHack?

    Ваше приведение не сработает, если тип экземпляра несовместим с типом, к которому его надо привести. Например, строка String не имеет ничего общего с Int, поэтому приведение String к Int вызовет исключение ClassCastException, которое может вызвать сбой программы. (Помните, что приведение и преобразование - это разные вещи. Некоторые строки можно преобразовать в целые числа, но нельзя строковый тип String привести к числовому типу Int).

    Оператор приведения типа позволяет попытаться привести любую переменную к любому типу, но ответственность за результат приведения полностью лежит на вас. Если операция приведения типа может быть небезопасной, заключите ее в блок try/catch. Тем не менее лучше избегать приведения типов, если вы не уверены, что оно пройдет успешно.

    На следующем шаге мы рассмотрим умное приведение типа.




Предыдущий шаг Содержание Следующий шаг