На этом шаге мы рассмотрим работу с методами свойств Java в Kotlin.
Kotlin и Java обрабатывают переменные класса по-разному. Java использует поля и обычно предоставляет доступ к ним через методы чтения и записи. Свойства в Kotlin, как вы уже видели, ограничивают доступ к полям и автоматически предлагают методы чтения и записи.
На прошлом шаге вы добавили общедоступное поле hitPoints в Jhava. Этот пример помог продемонстрировать отображение типов, но он нарушает принципы инкапсуляции и поэтому является не лучшим решением. В Java к полям надо обращаться или изменять их с помощью методов чтения и записи. Методы чтения используются для извлечения данных, а методы записи - для их изменения.
Объявите поле hitPoints приватным и добавьте метод чтения, чтобы hitPoints можно было прочитать, но нельзя изменить.
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class Jhava { private int hitPoints = 52489112; @NotNull public String utterGreeting() { return "BLARGH"; } @Nullable public String determineFriendshipLevel() { return null; } public int getHitPoints() { return hitPoints; } }
Рис.1. Объявление поля в java (Jhava.java)
Вернитесь в Hero.kt. Код все еще компилируется. Мы говорили о том, что Kotlin избавляет от необходимости использовать синтаксис вызова методов чтения/записи. Это означает, что вы можете использовать синтаксис, который выглядит так, как если бы вы обращались к полям и свойствам напрямую, и одновременно с этим поддерживает инкапсуляцию. Поэтому хотя getHitPoints и имеет префикс get, в Kotlin его можно отбросить и обращаться напрямую к hitPoints. Эта особенность стирает барьер между Kotlin и Java.
Это относится и к методам записи. На данный момент герой и монстр уже хорошо знакомы и хотят развить отношения. Герой хотел бы расширить словарный запас монстра. Переместите приветствие монстра в поле и добавьте для него методы чтения и записи, чтобы герой мог изменить приветствие и обучить монстра речи.
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class Jhava { private int hitPoints = 52489112; private String greeting = "BLARGH"; @NotNull public String utterGreeting() { return greeting; } . . . . . public int getHitPoints() { return hitPoints; } public String getGreeting() { return greeting; } public void setGreeting(String greeting) { this.greeting = greeting; } }
Рис.2. Замена greeting в Java (Jhava.java)
В Hero.kt исправьте adversary.greeting.
fun main(args: Array<String>) { val adversary = Jhava() val friendshipLevel = adversary.determineFriendshipLevel() println(friendshipLevel?.toLowerCase() ?: "It's complicated.") val adversaryHitPoints: Int = adversary.hitPoints println(adversaryHitPoints.dec()) println(adversaryHitPoints.javaClass) adversary.greeting = "Hello, Hero." println(adversary.utterGreeting()) }
Рис.3. Настройка поля Java из Kotlin (Hero.kt)
Чтобы изменить поле в Java, вместо вызова его метода записи можно использовать инструкцию присваивания. У вас есть преимущества синтаксиса Kotlin даже при работе с Java API. Запустите Hero.kt и посмотрите, научил ли герой монстра новым словам.
Рис.4. Результат работы приложения
На следующем шаге мы рассмотрим, что происходит за пределами класса.