Освой Kotlin играючи
/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000
Существуют четыре модификатора доступа (или видимости):
Модификаторы ставятся перед классом, функцией или свойством и позволяют гибко настраивать степень доступности из разных участков кода.
Модификатор public используется по умолчанию и его можно не указывать. Но иногда можно явно указать, чтобы лишний раз напомнить, что доступ к классу возможен отовсюду.
Члены класса и объявления верхнего уровня с данным модификатором также доступны повсюду.
Если функция или свойство имеют модификатор private, то они доступны только внутри самого класса.
В одном файле можно объявить классы, а также функции топ-уровня и свойства топ-уровня с модификатором private. Тогда они могут взаимодействовать между собой внутри этого файла.
Рассмотрим пример. Создадим файл TopLevel.kt.
private var index = 0 // свойство топ-уровня
private class Cat(val name: String) // класс топ-уровня
private fun recordCat( // функция топ-уровня
cat: Cat
) {
println("Кот #$index: ${cat.name}")
index++
}
fun recordCats() {
recordCat(Cat("Васька"))
recordCat(Cat("Барсик"))
}
fun getCatsCount() {
println("Коты в количестве $index приветствуют вас!")
}
Мы объявили закрытое свойство index, однако оно доступно в закрытой функции recordCat() и открытой функции getCatsCount(), потому то все они находятся в одном файле.
Аналогично закрытый класс Cat доступен функции recordCat() и т.д.
Попробуем создать экземпляр класса Cat в MainActivity.kt. Студия не позволит вам сделать этого.
По той же причине мы не сможем вызвать функцию recordCat().
А вот две функции без модификаторов мы можем вызвать.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
recordCats()
getCatsCount()
}
Эти функции обращаются к закрытым классам и свойствам, но так как они объявлены в одном файле, то могут получить доступ к ним.
Управление доступом часто используют при создании класса, когда нужно разграничить область видимости у разных свойств и функций. Создадим снова класс Cat следующим образом.
class Cat(private var isReady: Boolean) {
private fun scratch() = println("Цап-царап")
public fun bite() = println("Я делаю кусь")
fun hooligan() {
isReady = true
scratch()
bite()
}
}
Свойство isReady не будет доступно из других мест, его можно поменять только внутри класса, в нашем случае в функции hooligan(). Также мы не сможем вызвать функцию scratch(). Остальные функции доступны. И если мы вызовем функцию hooligan(), то она в свою очередь под капотом может вызвать закрытую функцию scratch().
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val cat = Cat(false)
cat.bite()
// Нельзя обратиться напрямую
// cat.isReady
// cat.scratch()
cat.hooligan()
}
Подобный подход удобен при разработке библиотек. Вы как разработчик можете создавать вспомогательные функции и свойства, которые доступны только внутри вашего класса. А программист, который будет пользоваться вашей библиотекой, сможет вызывать только разрешённые вами функции и свойства.
В Kotlin добавлен новый модификатор internal, обеспечивающий видимость в границах модуля. Модуль - это набор файлов, компилируемых вместе (модуль в IDEA, проект Eclipse, Maven, Gradle и т.д.). Члены класса и объявления верхнего уровня доступны в пределах модуля.
Члены класса с модификатором protected доступны в подклассах.